什么是yield?
yield 关键字 returns data from a generator function:
生成器函数的核心是 yield 关键字。在最简单的形式中,yield 语句看起来很像 return 语句,只是它不是停止函数的执行并返回,而是为在生成器上循环的代码提供一个值并暂停生成器函数的执行。
什么是生成器函数?
生成器函数实际上是编写Iterator 的更紧凑和更有效的方式。它允许您定义一个函数(您的xrange),该函数将计算并返回值您是looping over it:
function xrange($min, $max) {
for ($i = $min; $i <= $max; $i++) {
yield $i;
}
}
[…]
foreach (xrange(1, 10) as $key => $value) {
echo "$key => $value", PHP_EOL;
}
这将创建以下输出:
0 => 1
1 => 2
…
9 => 10
您也可以通过使用控制foreach中的$key
yield $someKey => $someValue;
在生成器函数中,$someKey 是您希望出现的任何内容,$key 和 $someValue 是 $val 中的值。在问题的示例中,$i。
与普通函数有什么区别?
现在您可能想知道为什么我们不简单地使用 PHP 的原生 range function 来实现该输出。你是对的。输出将是相同的。不同之处在于我们如何到达那里。
当我们使用range PHP 时,将执行它,在内存中创建整个数字数组并将return 该整个数组 放到foreach 循环中,然后循环遍历它并输出值。换句话说,foreach 将对数组本身进行操作。 range 函数和 foreach 只“交谈”一次。把它想象成在邮件中收到一个包裹。送货员会把包裹递给你然后离开。然后你打开整个包裹,取出里面的任何东西。
当我们使用生成器函数时,PHP 会进入该函数并执行它,直到它遇到结尾或yield 关键字。当它遇到yield 时,它会将当时的值返回到外部循环。然后它回到生成器函数并从它产生的地方继续。由于您的 xrange 包含一个 for 循环,因此它将执行并让步,直到达到 $max。把它想象成foreach 和打乒乓球的发电机。
我为什么需要它?
显然,生成器可用于解决内存限制。根据您的环境,执行range(1, 1000000) 会使您的脚本致命,而使用生成器同样可以正常工作。或者正如维基百科所说:
由于生成器仅根据需要计算其产生的值,因此它们对于表示昂贵或不可能一次计算的序列非常有用。这些包括例如无限序列和实时数据流。
生成器也应该很快。但请记住,当我们谈论快速时,我们通常会谈论非常少的数字。因此,在您现在运行并更改所有代码以使用生成器之前,请先做一个基准测试,看看它在哪里有意义。
生成器的另一个用例是异步协程。 yield 关键字不仅返回值,而且还接受它们。有关这方面的详细信息,请参阅下面链接的两篇优秀的博客文章。
什么时候可以使用yield?
PHP 5.5 中引入了生成器。尝试在该版本之前使用yield 会导致各种解析错误,具体取决于关键字后面的代码。因此,如果您从该代码中收到解析错误,请更新您的 PHP。
来源和进一步阅读: