关于 PHP 的 yield 的一个奇怪的问题

2021-06-22 11:36:26 +08:00
 rockyliang

最近在学习 PHP yield 相关的知识,遇到了一个搞不懂的问题,直接上代码:

function gen() {
    for ($i = 0; $i < 3; $i++) {
        echo "For index:$i\n";
        $tmp = (yield $i);
    }
}

$gen = gen();
foreach ($gen as $val) {
    echo "Generator return:$val\n";
}
echo "Finish\n";

上面这段代码会输出:

For index:0
Generator return:0
For index:1
Generator return:1
For index:2
Generator return:2
Finish

但是,只要在代码里加多一句send的代码,如下:

function gen() {
    for ($i = 0; $i < 3; $i++) {
        echo "For index:$i\n";
        $tmp = (yield $i);
    }
}

$gen = gen();
foreach ($gen as $val) {
    echo "Generator return:$val\n";
    $gen->send(++$val); // 这句是新加的代码
}
echo "Finish\n";

然后输出就会变成(相比原输出,少了一行"Generator return:1"):

For index:0
Generator return:0
For index:1
For index:2
Generator return:2
Finish

问题:在这个例子里,为什么加了一句 send 后,输出内容就改变了?

1895 次点击
所在节点    PHP
3 条回复
ykw
2021-06-22 13:30:08 +08:00
如果在调用此方法时生成器不在 yield 表达式,**则在发送值之前首先让它前进到下一个 yield 表达式**。因此,没有必要使用 Generator::next() 调用来“准备”PHP 生成器。

`send()` 就迭代了一次。
rockyliang
2021-06-22 13:57:30 +08:00
@ykw 好吧,还真是这样,调用 send()后,生成器继续执行,进入到了第二轮循环($i = 1 ),然后 1 作为 send()的返回值返回给了外部,外部没有打印出来,所以输出内容就少了一行。明白了,谢谢你:)
weirdo
2021-06-22 22:58:11 +08:00
send() ,就直接跑到下一次 yield 了呀

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/785028

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX