PHP中的收益率意味着什么?
我最近偶然发现了这个代码:
function xrange($min, $max)
{
for ($i = $min; $i <= $max; $i++) {
yield $i;
}
}
我从来没有见过这个yield
关键字。 试图运行我得到的代码
解析错误:语法错误,第x行出现意外的T_VARIABLE
那么这个yield
关键字是什么? 它甚至是有效的PHP? 如果是这样,我该如何使用它?
什么是yield
?
yield
关键字从一个生成器函数返回数据:
生成器函数的核心是yield关键字。 在最简单的形式中,yield语句看起来很像return语句,不同之处在于,yield并不是停止函数的执行并返回,而是为循环遍历生成器的代码提供一个值,并暂停生成器函数的执行。
什么是发电机功能?
生成器函数实际上是编写迭代器的更紧凑和更高效的方式。 它允许你定义一个函数(你的xrange
),它将在循环时计算并返回值:
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
函数来实现该输出。 对,你是。 输出将是相同的。 不同的是我们如何到达那里。
当我们使用range
PHP时,将执行它,在内存中创建整个数组数组,然后return
整个数组return
到foreach
循环,然后循环它并输出值。 换句话说, foreach
将在数组本身上运行。 range
函数和foreach
只“说”一次。 想想它就像在邮件中获取包一样。 送货员将把包裹交给你,然后离开。 然后你打开整个包裹,拿出里面的东西。
当我们使用生成器函数时,PHP将进入函数并执行它,直到它满足结束或yield
关键字。 当它满足yield
,它会将当时的价值返回到外部循环。 然后它回到发电机的功能,并继续从它产生的地方。 由于你的xrange
拥有一个for
循环,它会执行并产生,直到达到$max
。 把它看作是像foreach
和发电机打乒乓球一样。
为什么我需要这个?
显然,可以使用生成器来解决内存限制。 取决于你的环境,做一个range(1, 1000000)
会致命你的脚本,而同样的发电机将工作正常。 或者如维基百科所说:
由于生成器仅在需求时计算其生成的值,因此它们对于表示一次性计算昂贵或不可能的序列很有用。 这些包括例如无限序列和实时数据流。
发电机也应该是相当快的。 但请记住,当我们谈论得很快的时候,我们通常会以非常小的数字说话。 所以,在你现在跑掉并改变你所有的代码来使用生成器之前,先做一个基准来看看它的意义。
另一个用于生成器的用例是异步协程。 yield
关键字不仅返回值,还接受它们。 有关详情,请参阅下面链接的两篇优秀博客文章。
从什么时候我可以使用yield
?
生成器已经在PHP 5.5中引入。 尝试在该版本之前使用yield
会导致各种解析错误,具体取决于关键字后面的代码。 因此,如果您从该代码中获得解析错误,请更新您的PHP。
来源和进一步阅读:
yield
关键字用于定义PHP 5.5中的“生成器”。 好的,那么什么是发电机?
从php.net:
生成器提供了一种简单的方法来实现简单的迭代器,而无需实现实现Iterator接口的类的开销或复杂性。
一个生成器允许你编写使用foreach遍历一组数据的代码,而不需要在内存中建立一个数组,这可能会导致你超出内存限制,或者需要大量的处理时间来生成。 相反,您可以编写一个生成器函数,它与普通函数相同,除了不必返回一次,生成器可以根据需要产生尽可能多的次数,以便提供要迭代的值。
从这个地方:发电机=发电机,其他功能(只是一个简单的功能)=功能。
所以,它们在以下情况下很有用
你需要做简单的事情(或简单的事情);
生成器真的非常简单,然后实现Iterator接口。 另一方面是,发电机的功能较差。 比较它们。
您需要生成大量的数据 - 节省内存;
实际上为了节省内存,我们可以通过函数为每个循环迭代生成所需的数据,迭代后使用垃圾。 所以这里的要点是 - 清晰的代码和可能的性能。 看看什么更适合你的需求。
您需要生成序列,这取决于中间值;
这是先前思想的延伸。 与功能相比,发电机可以使事情变得更简单。 检查Fibonacci示例,并尝试在没有生成器的情况下创建序列。 在这种情况下,发生器也可以更快地工作,至少因为将中间值存储在局部变量中;
你需要提高性能。
他们可以在某些情况下工作得更快,然后执行功能(见前面的好处)
简单的例子
<?php
echo '#start main# ';
function a(){
echo '{start[';
for($i=1; $i<=9; $i++)
yield $i;
echo ']end} ';
}
foreach(a() as $v)
echo $v.',';
echo '#end main#';
?>
产量
#start main# {start[1,2,3,4,5,6,7,8,9,]end} #end main#
链接地址: http://www.djcxy.com/p/58065.html
上一篇: What does yield mean in PHP?
下一篇: The use of htmlspecialchars() or htmlentities() in prepared statements