首页 > 解决方案 > 为什么在 PHP 中使用 Generator::throw 会在 throw 后忽略产生的值

问题描述

我试图理解为什么Generator::throwException使调用者在被捕获后不接收值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 这样的值

该文档并未表明这是预期的行为

向生成器中抛出异常并恢复生成器的执行。行为将与当前的 yield 表达式被替换为 throw $exception 语句相同。

这是php中的错误吗?

标签: phpgeneratorthrow

解决方案


正如您从 PHP 文档中引用的那样:

...行为将与当前的yield 表达式被替换为 throw $exception 语句相同。

这是预期的行为。


推荐阅读