收益率在 PHP 中意味着什么?
我最近偶然发现了这个代码:
function xrange($min, $max)
{
for ($i = $min; $i <= $max; $i++) {
yield $i;
}
}
我以前从未见过这个关键字。尝试运行我获得的代码yield
解析错误:语法错误,x 行上的意外T_VARIABLE
那么这个关键词是什么呢?它甚至有效的PHP吗?如果是,我该如何使用它?yield
我最近偶然发现了这个代码:
function xrange($min, $max)
{
for ($i = $min; $i <= $max; $i++) {
yield $i;
}
}
我以前从未见过这个关键字。尝试运行我获得的代码yield
解析错误:语法错误,x 行上的意外T_VARIABLE
那么这个关键词是什么呢?它甚至有效的PHP吗?如果是,我该如何使用它?yield
yield
关键字从生成器函数返回数据:yield
生成器函数的核心是 yield 关键字。在最简单的形式中,yield 语句看起来很像 return 语句,不同之处在于 yield 不是停止函数的执行并返回,而是为循环访问生成器的代码提供一个值,并暂停生成器函数的执行。
生成器函数实际上是编写迭代器的一种更紧凑、更有效的方法。它允许您定义一个函数(您的),该函数将在您循环访问它时计算并返回值:xrange
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
您还可以通过使用$key
foreach
yield $someKey => $someValue;
在生成器函数中,是您想要显示的任何内容,并且是 中的值。在问题的示例中,这是 .$someKey
$key
$someValue
$val
$i
现在您可能想知道为什么我们不简单地使用PHP的本机范围
函数来实现该输出。你是对的。输出将相同。不同之处在于我们如何到达那里。
当我们使用PHP时,将执行它,在内存中创建整个数字数组,并将整个数组创建到循环中,然后循环将遍历它并输出值。换句话说,will 在数组本身上运行。该功能只有一次“说话”。把它想象成在邮件中得到一个包裹。送货员会把包裹递给你并离开。然后你打开整个包装,取出里面的任何东西。range
return
foreach
foreach
range
foreach
当我们使用生成器函数时,PHP 将单步执行该函数并执行它,直到它满足 end 或关键字。当它遇到 a 时,它将向外部循环返回当时的任何值。然后它返回到生成器函数,并从它产生的地方继续。由于您持有循环,因此它将执行并产生,直到达到该循环。把它想象成和发电机打乒乓球。yield
yield
xrange
for
$max
foreach
显然,生成器可用于解决内存限制。根据您的环境,执行 a 将使您的脚本致命,而对生成器执行此操作将正常工作。或者正如维基百科所说:range(1, 1000000)
由于生成器仅按需计算其生成值,因此它们对于表示昂贵或不可能一次计算的序列非常有用。这些包括例如无限序列和实时数据流。
发电机也应该非常快。但请记住,当我们谈论快速时,我们通常谈论的人数很少。因此,在你现在运行并将所有代码更改为使用生成器之前,请进行基准测试以查看其意义所在。
生成器的另一个用例是异步协程。关键字不仅返回值,而且还接受值。有关此内容的详细信息,请参阅下面链接的两篇优秀博客文章。yield
yield
PHP 5.5 中引入了生成器。尝试在该版本之前使用将导致各种分析错误,具体取决于关键字后面的代码。因此,如果您从该代码中收到解析错误,请更新PHP。yield
此函数使用 yield:
function a($items) {
foreach ($items as $item) {
yield $item + 1;
}
}
它几乎与此相同,没有:
function b($items) {
$result = [];
foreach ($items as $item) {
$result[] = $item + 1;
}
return $result;
}
唯一的区别是返回一个生成器,只返回一个简单的数组。您可以同时迭代两者。a()
b()
此外,第一个不分配完整的数组,因此对内存的要求较低。