Какие-либо альтернативы для использования "yield from" внутри генератора ссылок? - PullRequest
0 голосов
/ 09 июля 2019

Я хочу использовать некоторые методы, которые используют Generator s в качестве типа возврата и ссылки. Однако проблема в том, что метод получает возвращаемое значение другого метода, которое возвращается по ссылке и имеет значение Generator, и возвращает его по ссылке. Кроме того, почти все методы возвращают значение после получения одного или нескольких значений.

Давайте посмотрим в коде:

class YieldFromByReferenceTest
{
    public $data = [
        "Ubuntu",
        "CentOS",
        "Fedora"
    ];

    protected function &sampleGenerator(): \Generator
    {
        foreach ($this->data as $key => &$datum) {
            yield $key => $datum;
        }
        // This is just a sample return type
        return true;
    }

    public function &useGenerator(): \Generator
    {
        $generator = $this->sampleGenerator();

        // Return $generator?
    }
}

Во-первых, yield from пришло мне в голову. Однако, когда я пытаюсь использовать его, он выдает мне следующую ошибку:

PHP Fatal error: Cannot use "yield from" inside a by-reference generator in ./test.php on line xx

Это выглядит странно для меня. Я не знаю, почему это не работает (как мне кажется, это должно работать). Итак, мои вопросы:

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

  2. Каковы альтернативные решения?

Спасибо!

1 Ответ

0 голосов
/ 09 июля 2019

Я собираюсь опубликовать два решения (пожалуйста, подумайте о замене следующих кодов частью: // Return $generator? в коде в вопросе), но я не могу ответить на свой первый вопрос.

Сдача и возврат

Одно из возможных решений - получить все значения из sampleGenerator() и затем вернуть его возвращаемое значение:

// Please notice the &
foreach ($generator as $key => &$value) {
    yield $key => $value;
}
return $generator->getReturn();

Работает отлично и предотвращаетошибки, даже если используются вложенные генераторы или если генератор не выдает или не возвращает никаких значений.Однако в некоторых случаях, как по мне, код станет труднее читать из-за его частого использования.

Возврат самого генератора

Проще говоря, вы можете вернуть возвращенный генератор:

return $generator;

На первый взгляд, это выглядит проще, но если вы работаете над некоторыми сложными частями кода, то это становится немного сложнее.Просто имейте в виду, что если вы не используете оператор yield где-то в функции, он возвращает экземпляр Generator и не является функцией-генератором.Несмотря на это, как и в случае со мной, ваша проблема может быть решена добавлением пустого дохода (обратите внимание, это будет генератор):

return $generator;
yield;

Примечание : Возможно,очевидно, но это не всегда рабочие решения.Вы должны рассмотреть свою собственную проблему и затем попытаться решить ее;поэтому вам могут понадобиться оба способа, чтобы выполнить работу!

Надеюсь, это поможет!

...