在通过引用生成器内部使用“ yield from”的其他选择吗?

时间:2019-07-09 17:27:52

标签: php generator yield return-by-reference yield-from

我想使用一些使用Generator作为返回类型和副引用的方法。但是,问题在于一个方法获取另一个方法的返回值,该返回值由引用返回且为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 :(得分:0)

我将发布两个解决方案(请考虑将以下代码替换为问题代码中的// Return $generator?部分),但我无法真正回答我的第一个问题。

屈服并返回

一种可能的解决方案是从sampleGenerator()产生所有值,然后返回其返回值:

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

即使使用嵌套生成器或生成器不产生或不返回任何值,它也可以完美运行并防止错误。但是,在某些情况下,对我而言,由于使用过多,因此代码将变得更难阅读。

自行退还发电机

简单来说,您可以返回返回的生成器:

return $generator;

乍一看,它看起来更简单,但是如果您正在处理一些复杂的代码,那么它将变得有些复杂。请记住,除非在函数的某处使用yield语句,否则它将返回Generator实例,并且它不是生成器函数。尽管如此,就像发生在我身上的情况一样,可以通过添加空收益来解决您的问题(请注意,它将是一个生成器):

return $generator;
yield;

注意:这很明显,但这并不是始终可行的解决方案。您应该考虑自己的问题,然后尝试解决它;因此,您可能需要两种方式才能完成工作!

希望有帮助!