ClosedGeneratorException

ClosedGeneratorException

当查看php 7.0和php7.1中get_declared_classes()的输出时,我注意到一个ClosedGeneratorException
手册中没有much mention of it的内容,而且似乎也没有在手册中的Predefined ExceptionsSPL exceptions条目中列出。
甚至源代码也会not hold much information about it
那么,什么是ClosedGeneratorException
(这是干什么的?什么时候发生?什么时候使用?)

最佳答案

根据评论中的回答,我能够回答自己的问题
code in the PHP core that throws this exception表示:

    /* php-src/Zend/zend_generators.c */

    zend_throw_exception(
        zend_ce_ClosedGeneratorException,
        "Generator yielded from aborted, no return value available",
        0
    );

有一个an article on airbrake.io进入了ClosedGeneratorException的细节:
试图在已关闭或终止的生成器上执行遍历时发生ClosedGeneratorException
换句话说,当生成器的值用完时,请求新值将触发此异常。(1)
基于this test from the PHP core我构建了两个场景,其中一个ClosedGeneratorException被抛出(并捕获)。
通过从内部生成器中抛出异常(使用yield from syntax),可以很容易地模拟此行为。异常仅从生成器内部引发。(尽管可以在发电机外部捕捉到)。
这两个场景附在下面。两个例子都可以在ideone.com上看到(2)(3)
两个示例的输出如下:
在发电机内部捕捉ClosedGeneratorException(2)
Generator: 0
1
Generator: 1
Caught ClosedGeneratorException

在发电机外部捕捉ClosedGeneratorException(3)
Generator: 0
Caught Generic Exception
Generator: 1
Caught ClosedGeneratorException

脚注
本文提供了一个触发异常的示例,但看起来该示例不起作用(因为抛出了一个常规异常)。
在发电机内捕获ClosedGeneratorExceptionhttps://ideone.com/FxTLe9
在发电机外部捕捉ClosedGeneratorExceptionhttps://ideone.com/ipEgKx
代码示例
在发电机内部捕获:
<?php

class CustomException extends Exception {}

function from() {
    yield 1;
    throw new CustomException();
}

function gen($gen) {
    try {
        yield from $gen;
    } catch (\ClosedGeneratorException $e) {
        yield "Caught ClosedGeneratorException";
    } catch (\Exception $e) {
        yield "Caught Generic Exception";
    }
}

$gen = from();
$gens[] = gen($gen);
$gens[] = gen($gen);

foreach ($gens as $g) {
    $g->current(); // init.
}

foreach ($gens as $i => $g) {
    print "Generator: $i\n";
    print $g->current()."\n";
    $g->next();
}

在发电机外部捕获:
<?php

class CustomException extends Exception {}

function from() {
    yield 1;
    throw new CustomException();
}

function gen($gen) {
    yield from $gen;
}

$gen = from();
$gens[] = gen($gen);
$gens[] = gen($gen);

foreach ($gens as $g) {
    $g->current(); // init.
}

foreach ($gens as $i => $g) {
    print "Generator: $i\n";
    try {
        $g->current();
        $g->next();
    } catch (\ClosedGeneratorException $e) {
        print "Caught ClosedGeneratorException\n";
    } catch (\Exception $e) {
        print "Caught Generic Exception\n";
    }
}

关于php - 在PHP中,“ClosedGeneratorException”是什么?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/47183250/

10-13 01:00