0

我想使用一些使用Generators 作为返回类型和引用的方法。但是,问题是一个方法获取另一个方法的返回值,即按引用返回并且是 a 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. 有哪些替代解决方案?

谢谢!

4

1 回答 1

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;

注意:这可能很明显,但这些并非总是有效的解决方案。您应该考虑自己的问题,然后尝试解决它;所以,你可能需要两种方法来完成工作!

希望能帮助到你!

于 2019-07-09T17:27:52.507 回答