我试图理解为什么Generator::throw使调用者在Exception
中捕获Generator
之后不接收值。
<?php
class moo
{
public function run()
{
$generator = $this->getIterator();
foreach ($generator as $item) {
try {
error_log("PROCESS: {$item}");
if ($item % 2 === 0) {
error_log("throwing InvalidArgumentException $item");
throw new InvalidArgumentException($item);
}
} catch (Throwable $e) {
$generator->throw($e);
}
}
}
private function getIterator()
{
foreach (range(1, 6) as $item) {
try {
yield $item;
} catch (Throwable $e) {
$class = get_class($e);
error_log("GOT[$class] in generator: {$e->getMessage()}");
}
}
}
}
$m = new moo();
$m->run();
上面的代码打印:
PROCESS: 1
PROCESS: 2
throwing InvalidArgumentException 2
GOT[InvalidArgumentException] in generator: 2
PROCESS: 4
throwing InvalidArgumentException 4
GOT[InvalidArgumentException] in generator: 4
PROCESS: 6
throwing InvalidArgumentException 6
GOT[InvalidArgumentException] in generator: 6
在run
方法中循环不会看到3和5之类的值
文档没有表明这是预期的行为
将异常引发到生成器中,并继续执行 发电机。行为将与当前收益率相同 表达式被替换为throw $ exception语句。
这是php中的错误吗?
答案 0 :(得分:2)
当您引用PHP文档时:
...行为与当前 yield表达式相同 被替换为throw $ exception语句。
这是预期的行为。
答案 1 :(得分:1)
如Paul Crovella和Łukasz Jakubek所述,该值“丢失”到返回值$generator->throw()
中。
我已经创建了一个项目,如果将Generator包裹起来,则yield
值将按顺序出现在yield消费者:https://github.com/glensc/ThrowableGenerator
编辑:还添加了:: send()包装器:https://github.com/glensc/ThrowableGenerator/releases/tag/1.1.0