php - 为什么在 PHP 中使用 Generator::throw 会忽略 throw 后的生成值

标签 php generator throw

我试图理解为什么 Generator::throw使调用者在 Generator 中捕获 Exception 后不再接收值。

<?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 这样的值

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

Throws an exception into the generator and resumes execution of the generator. The behavior will be the same as if the current yield expression was replaced with a throw $exception statement.

这是 php 中的错误吗?

最佳答案

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

...The behavior will be the same as if the current yield expression was replaced with a throw $exception statement.

这是预期的行为。

关于php - 为什么在 PHP 中使用 Generator::throw 会忽略 throw 后的生成值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51382259/

相关文章:

php - <tr> 和 <td> 标签覆盖 <pre>

php - 在没有网络服务器的情况下在 linux 上使用 php 从文件夹发送电子邮件

php - MySQL 查询末尾的 "ORDER BY order"导致问题

php - Exception、InvalidArgumentException 或 UnexpectedValueException 之间有什么区别?

php - connect() 到 unix :/tmp/php-fpm. sock 失败(2:没有这样的文件或目录)

recursion - Racket如何像Python一样定义一个递归生成器?

javascript - 使用生成器函数的输入和输出

python - 生成器是否具有时间效率?

swift - 从闭包中抛出错误

c++ - 为什么 "dynamic exception"保证会导致开销?