gpt4 book ai didi

php - Generator::send 是如何工作的?

转载 作者:可可西里 更新时间:2023-11-01 13:25:50 25 4
gpt4 key购买 nike

通常我不会对语言结构感到困惑,但我无法弄清这里发生的事情。

<?php

function action() {
for($i=0; $i<10; ++$i) {
$ans = (yield expensive($i));
echo "action $ans\n";
}
}

function expensive($i) {
return $i*2;
}

$gen = action();
foreach($gen as $x) {
echo "loop $x\n";
$gen->send($x);
}

打印:

loop 0
action 0
action
loop 4
action 4
action
loop 8
action 8
action
loop 12
action 12
action
loop 16
action 16
action

因此,我的循环的每 2 次迭代都会被跳过,并且我会定期为 $ans 获取 NULL。什么??

我以为 $ans 会收到 $gen->send 的结果,如果我在下一个 yield 之前没有发送任何东西,then $ans 将为空,但我总是在每次迭代时发送一些东西,那么这里发生了什么?

最佳答案

这是一个文档问题。这是一个 PHP 开发人员 wrote on a bug report :

next() and send() both advance the generator. That's how generators work. Using next(), explicitly or implicitly, means there's no way to pass a value back through the yield and thus the code will get null - just like when trying to get the return value from a function that doesn't return anything.

换句话说,您不能在 foreach 中使用 send() 并期望得到有意义的结果。


实际foreach调用next() after each iteration .

/** @return Generator */
function action() {
for ($i = 0; $i < 5; $i += 1) {
$answer = (yield $i * 2);
echo "received: $answer\n";
}
}


$gen = action();
while ($gen->valid()) {
$x = $gen->current();
echo "sending $x\n";
$gen->send($x);
$gen->next();
}

现在我们添加了它,代码又开始出错了:

sending 0
received: 0
received:
sending 4
received: 4
received:
sending 8
received: 8

如果我们删除有问题的 next(),代码将按预期工作。

$gen = action();
while ($gen->valid()) {
$x = $gen->current();
echo "sending $x\n";
$gen->send($x);
//$gen->next();
}

输出:

sending 0
received: 0
sending 2
received: 2
sending 4
received: 4
sending 6
received: 6
sending 8
received: 8

对我来说听起来像是一个错误。 Even HHVM fails with a fatal error.

关于php - Generator::send 是如何工作的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37817315/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com