【问题标题】:Difference between `yield from $generator` and `return $generator`?`yield from $generator` 和 `return $generator` 之间的区别?
【发布时间】:2025-12-05 05:00:01
【问题描述】:

我有一个返回生成器的函数。目前它使用yield from

function foo()
{
    $generator = getGenerator();
    // some other stuff (no yields!)
    yield from $generator;
}

如果我将 yield from 替换为简单的 return,在这种情况下会改变什么吗?也许在执行中?还是性能? yield from 会生成一个新的“外部”迭代器吗?

我知道,在其他情况下yield from 可以更灵活,因为我可以多次使用它,甚至可以将它与简单的yields 混合使用,但这对我的情况无关紧要。

【问题讨论】:

  • 请阅读 docs 中关于使用yield from 后跟iterator_to_array()caution

标签: php return generator yield-from


【解决方案1】:

当您像上面那样在方法末尾使用一次yield from 时,这不会改变方法返回的内容。但是方法内部的代码还是有区别的:在迭代开始的时候回退迭代器时会调用yield from之前的代码,而调用函数时会执行return之前的代码,就像这样函数现在只是一个普通函数(实际上,这不是yield from特有的。这是yield的行为。见https://3v4l.org/jnPvC的证明)。

yield from 的一大优点是你可以在函数中多次使用它,它将所有迭代器的值组合到一个迭代器中。

【讨论】:

    【解决方案2】:

    在您的情况下,将 yield from 更改为 return 会产生相同的结果。但是,如果您在 return 之前有 yield 语句,则它不会合并来自 getGenerator() 的值。

    function gen_1()
    {
        yield 1;
    }
    
    function gen_2()
    {
        return gen_1();
    }
    
    function gen_3()
    {
        yield 2;
        return gen_1();
    }
    
    function gen_4()
    {
        yield 2;
        yield from gen_1();
    }
    
    echo "testing gen_2\n";
    foreach (gen_2() as $v) {
        echo $v  . "\n";
    }
    
    echo "testing gen_3\n";
    foreach (gen_3() as $v) {
        echo $v  . "\n";
    }
    
    echo "testing gen_4\n";
    foreach (gen_4() as $v) {
        echo $v  . "\n";
    }
    

    输出:

    testing gen_2
    1
    testing gen_3
    2
    testing gen_4
    2
    1
    

    【讨论】:

      最近更新 更多