如何在 PHP 中从生成器中重置收益

How to reset yield from within a generator in PHP

我正在尝试设置一个耦合屈服函数。但是第二次调用该函数时,integrated 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();
}

但是没有用。

问题:这是预期的行为吗?我需要做什么才能重置 "inner" 生成器?

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

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

所以一个生成器默默地 returns 使用的生成器的键(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) 阻止了那个。

感谢输入!