1
function yielding()
{
    for ($i = 0; $i < 10; $i++) {
        var_dump(yield);
    }
}

$y = yielding();

foreach ($y as $val) {
    $y->send('foo');
}

输出:

string(3) "foo"
NULL
string(3) "foo"
NULL
string(3) "foo"
NULL
string(3) "foo"
NULL
string(3) "foo"

我预计输出为:10 次string(3) "foo",但输出为一NULL加一string(3) "foo"(9 次)。为什么?generator->send() 会跳过一次迭代吗?

4

2 回答 2

1

yield用于在生成器内部发送和接收值。来自生成器 RFC如果没有发送任何内容(例如在 foreach 迭代期间),则返回 null

因此,在您的代码中,生成器被恢复了两次:

  1. 一次 for ($y as $val)--yield在生成器内返回 null
  2. 一次 for $y->send('foo')--yield在生成器中返回 'foo'

当我运行你的代码时,我得到了 10 行输出,以 NULL 结尾

string(3) "foo"
NULL
...
string(3) "foo"
NULL
于 2013-11-05T15:26:49.510 回答
0

该功能send() is used to inject values
如果您想打印 foo 十次,那么以下可能会起作用(未测试)

function yielding()
{
    for ($i = 0; $i < 10; $i++) {
////get a value from the caller
        $string = yield;
        echo $string;
    }
}

编辑 :

$y = yielding();

for($k=0;$k<10;$k++)
    $y->send('foo');

这将打印十次。

当您迭代对象时会发生什么:(引用手册) “当您迭代该对象时(例如,通过 foreach 循环),PHP 将在每次需要一个值时调用生成器函数,然后保存状态当生成器产生一个值时生成器,以便在需要下一个值时可以恢复它。

一旦没有更多的值要产生,那么生成器函数就可以简单地退出,调用代码会继续,就像数组已经用完值一样。”

于 2013-11-05T05:38:01.643 回答