Разница между `yield from $generator` и`return $generator`?

У меня есть функция, которая возвращает генератор. На данный момент он использует yield from:

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

Если я заменю это yield from с простым returnэто что-то меняет в этом случае? Может быть в исполнении? Или производительность? Есть ли yield from создает новый "внешний" итератор?

Я знаю, в других случаях yield from может быть более гибким, потому что я могу использовать его несколько раз и даже смешать его с простым yieldс, однако это не имеет значения для моего случая.

2 ответа

В вашем случае меняется yield from в return дает тот же результат. Тем не менее, если у вас есть yield заявление перед return, он не будет объединять значения из 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

Когда вы используете yield from однажды в конце метода, как вы делаете выше, это не меняет того, что возвращает метод. Но есть разница для кода внутри метода: любой код до yield from вызывается при перемотке итератора в начале итерации, а код перед return выполняется при вызове функции, так как эта функция сейчас является просто нормальной функцией (на самом деле, это не относится к yield from, Это поведение yield, См. https://3v4l.org/jnPvC для доказательства).

Большое преимущество yield from является то, что вы можете использовать его несколько раз в функции, которая объединила значения всех итераторов в один итератор.

Другие вопросы по тегам