1

我正在尝试建立一个耦合的产量函数。但是当第二次调用该函数时,集成的 yield from 不会重置

我认为最简单的方法是用一个例子来展示:

代码示例

PHP

class GeneratorTest
{

    public function generatorA() {
        for ($i = 0; $i < 10; $i++) {
            yield $i;
        }
    }


    // Generators can yield from other generators
    public function generatorB() {
        yield from $this->generatorA();  // << why is this not reset?

        for($i = 0; $i < 26; $i++) {
            yield chr(65 + $i);
        }
    }

}


$gen = new GeneratorTest();

echo "Test 1 from Generator B<br>";
foreach ($gen->generatorB() as $item) {
    echo $item . "<br>";
}

echo "Test 2 from Generator B<br>";
print_r(iterator_to_array($gen->generatorB()));

预期的?

我希望“Test 2”的输出与“Test 1”相同。但实际上似乎生成器的产量在使用时没有重置。

编辑/重要:

正如@Ganesh Wagh 所指出的那样:在第二个“for-each”中调用生成器非常有效。只有在调用“iterator_to_array”时才会出现问题!这是预期的行为。

我试图在 generatorB 的末尾重置 generatorA,如下所示:

PHP

public function generatorB() {
    yield from $this->generatorA();

    for($i = 0; $i < 26; $i++) {
        yield chr(65 + $i);
    }
    $this->generatorA()->reset();
}

但无济于事。

问题:这是预期的行为吗?我该怎么做才能重置“内部”生成器?

4

1 回答 1

1

所有功劳归@Frankich!(第二条评论)

问题是,“iterator_to_array”评估了生成器的键。

所以生成器会默默地返回所用生成器的键(yield from):

echo "Test 1 from Generator B\n";
foreach ($gen->generatorB() as $key => $item) {
    echo $key . '=>' .  $item . "\n";
}

结果是:

1=>1
2=>2
...
0=>A
1=>B
2=>C
...

所以关键是: iterator_to_array($gen->generatorB()))被覆盖的地方(就像@Frankich指出的那样)!

并且只有: iterator_to_array($gen->generatorB()), false)阻止了这种情况。

谢谢输入!

于 2019-07-11T08:57:46.340 回答