duanqianruan8448 2019-07-09 17:27
浏览 91

在副引用生成器中使用“yield from”的任何替代方法?

I want to use some methods which use Generators as their return type and by-reference. However, the problem is that a method gets another method's return value, that is returned by-reference and is a Generator, and returns it by-reference. Plus, nearly all methods return a value after yielding one or more values.

Let's see in a code:

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?
    }
}

Firstly, yield from came in my mind. However, when I try to use it, it gives me the following error:

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

That looks strange to me. I don't know why it does not work (as in my mind, it should work). So, my questions are:

  1. In this case, why yield from doesn't work as expected and an error is generated? Shouldn't it work?

  2. What are the alternative solutions?

Thank you!

  • 写回答

1条回答 默认 最新

  • dongzhao8233 2019-07-09 17:27
    关注

    I'm going to post two solutions (please consider replacing the following codes with the part: // Return $generator? in the code in the question), but I can't really answer my first question.

    Yielding and Returning

    One possible solution is to yield all values from sampleGenerator() and then return its return value:

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

    It works perfectly, and prevents from errors, even if using nested generators or if a generator does not yield or return any values. However, in some cases, as for me, the code would become harder to read, because of using it a lot.

    Returning the Generator Itself

    Simply, you can return the returned generator:

    return $generator;
    

    At first glance, it looks simpler, but if you are working on some complicated pieces of code, then it becomes a bit complicated. Just keep in mind, unless you use a yield statement somewhere in the function, it returns a Generator instance, and it is not a generator function. Notwithstanding, just like what happened for me, your problem may be fixed by adding an empty yield (pay attention, it will be a generator):

    return $generator;
    yield;
    

    Note: It may be obvious, but these are not always-work solutions. You should consider your own problem and then try to fix it; so, you may need both ways to get the jobs done!

    Hope it helps!

    评论

报告相同问题?

悬赏问题

  • ¥15 ogg dd trandata 报错
  • ¥15 高缺失率数据如何选择填充方式
  • ¥50 potsgresql15备份问题
  • ¥15 Mac系统vs code使用phpstudy如何配置debug来调试php
  • ¥15 目前主流的音乐软件,像网易云音乐,QQ音乐他们的前端和后台部分是用的什么技术实现的?求解!
  • ¥60 pb数据库修改与连接
  • ¥15 spss统计中二分类变量和有序变量的相关性分析可以用kendall相关分析吗?
  • ¥15 拟通过pc下指令到安卓系统,如果追求响应速度,尽可能无延迟,是不是用安卓模拟器会优于实体的安卓手机?如果是,可以快多少毫秒?
  • ¥20 神经网络Sequential name=sequential, built=False
  • ¥16 Qphython 用xlrd读取excel报错