在PHP中yield是什么意思? [英] What does yield mean in PHP?

查看:136
本文介绍了在PHP中yield是什么意思?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我最近偶然发现了以下代码:

I've recently stumbled over this code:

function xrange($min, $max) 
{
    for ($i = $min; $i <= $max; $i++) {
        yield $i;
    }
}

我以前从未见过这个yield关键字.尝试运行我得到的代码

I've never seen this yield keyword before. Trying to run the code I get

解析错误:语法错误,第x行上出现意外的T_VARIABLE

Parse error: syntax error, unexpected T_VARIABLE on line x

那么这个yield关键字是什么?它甚至是有效的PHP吗?如果是的话,我该如何使用它?

So what is this yield keyword? Is it even valid PHP? And if it is, how do I use it?

推荐答案

什么是yield?

yield关键字从生成器函数返回数据:

What is yield?

The yield keyword returns data from a generator function:

生成器函数的核心是yield关键字.最简单的形式,yield语句看起来很像return语句,除了yield而不是停止执行函数并返回,而是为循环到生成器的代码提供一个值,并暂停生成器函数的执行.

The heart of a generator function is the yield keyword. In its simplest form, a yield statement looks much like a return statement, except that instead of stopping execution of the function and returning, yield instead provides a value to the code looping over the generator and pauses execution of the generator function.

什么是生成器函数?

生成器函数实际上是编写 Iterator .它允许您定义一个函数(您的xrange),当您

What is a generator function?

A generator function is effectively a more compact and efficient way to write an Iterator. It allows you to define a function (your xrange) that will calculate and return values while you are looping over it:

foreach (xrange(1, 10) as $key => $value) {
    echo "$key => $value", PHP_EOL;
}

这将创建以下输出:

0 => 1
1 => 2
…
9 => 10

您还可以通过使用控制foreach中的$key

You can also control the $key in the foreach by using

yield $someKey => $someValue;

在生成器函数中,$someKey是要显示的任何内容,而$key$someValue$val中的值.在问题的示例中为$i.

In the generator function, $someKey is whatever you want appear for $key and $someValue being the value in $val. In the question's example that's $i.

现在您可能想知道为什么我们不简单地使用PHP的本机 range函数实现该输出.是的,你是.输出将是相同的.区别在于我们到达那里的方式.

Now you might wonder why we are not simply using PHP's native range function to achieve that output. And right you are. The output would be the same. The difference is how we got there.

当我们使用range PHP时,将执行它,在内存中创建整个数字数组,并将整个数组创建到foreach循环,然后遍历它,并输出值.换句话说,foreach将对数组本身进行操作. range功能和foreach仅交谈"一次.可以将其想像成是在邮件中获取包裹.送货员将把包裹交给您,然后离开.然后解开整个包装,取出里面的任何东西.

When we use range PHP, will execute it, create the entire array of numbers in memory and return that entire array to the foreach loop which will then go over it and output the values. In other words, the foreach will operate on the array itself. The range function and the foreach only "talk" once. Think of it like getting a package in the mail. The delivery guy will hand you the package and leave. And then you unwrap the entire package, taking out whatever is in there.

当我们使用生成器函数时,PHP将进入该函数并执行,直到遇到结尾或yield关键字为止.当它遇到一个yield时,它将把当时的值返回外循环.然后,它返回到生成器函数,并从产生的地方继续.由于您的xrange拥有一个for循环,它将执行并屈服,直到到达$max为止.可以将其想象为foreach并使用生成器来打乒乓球.

When we use the generator function, PHP will step into the function and execute it until it either meets the end or a yield keyword. When it meets a yield, it will then return whatever is the value at that time to the outer loop. Then it goes back into the generator function and continues from where it yielded. Since your xrange holds a for loop, it will execute and yield until $max was reached. Think of it like the foreach and the generator playing ping pong.

很明显,生成器可用于解决内存限制.根据您的环境,执行range(1, 1000000)将会使您的脚本致命,而使用生成器执行同样的操作就可以了.或如Wikipedia所述:

Obviously, generators can be used to work around memory limits. Depending on your environment, doing a range(1, 1000000) will fatal your script whereas the same with a generator will just work fine. Or as Wikipedia puts it:

由于生成器仅根据需要计算其屈服值,因此它们对于表示可能昂贵或无法立即计算的序列很有用.这些包括无限序列和实时数据流.

Because generators compute their yielded values only on demand, they are useful for representing sequences that would be expensive or impossible to compute at once. These include e.g. infinite sequences and live data streams.

发电机也应该很快.但是请记住,当我们谈论快速时,我们通常会以很小的数量谈论.因此,在您开始运行并更改所有代码以使用生成器之前,请进行基准测试以了解它的意义.

Generators are also supposed to be pretty fast. But keep in mind that when we are talking about fast, we are usually talking in very small numbers. So before you now run off and change all your code to use generators, do a benchmark to see where it makes sense.

生成器的另一个用例是异步协程. yield关键字不仅返回值,而且还接受它们.有关详细信息,请参见下面链接的两篇优秀的博客文章.

Another Use Case for Generators is asynchronous coroutines. The yield keyword does not only return values but it also accepts them. For details on this, see the two excellent blog posts linked below.

生成器已在 PHP 5.5 中引入.尝试在该版本之前使用yield会导致各种解析错误,具体取决于关键字后面的代码.因此,如果您从该代码中遇到了解析错误,请更新您的PHP.

Generators have been introduced in PHP 5.5. Trying to use yield before that version will result in various parse errors, depending on the code that follows the keyword. So if you get a parse error from that code, update your PHP.

  • Official docs
  • The original RFC
  • kelunik's blog: An introduction to generators
  • ircmaxell's blog: What generators can do for you
  • NikiC's blog: Cooperative multitasking using coroutines in PHP
  • Co-operative PHP Multitasking
  • What is the difference between a generator and an array?
  • Wikipedia on Generators in general

这篇关于在PHP中yield是什么意思?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆