谁做PHP的YIELD->send()工作


who does PHP's YIELD->send() works?

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",但输出是 1 NULL 和 1 string(3) "foo"(9 倍)。 为什么呢?生成器>send() 会跳过一个迭代吗?

yield用于

在生成器内发送和接收值。来自生成器 RFC:如果未发送任何内容(例如,在每次迭代期间),则返回 null

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

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

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

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

函数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每次需要值时都会调用生成器函数,然后在生成器产生值时保存生成器的状态,以便在需要下一个值时可以恢复。

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