V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
rockyliang
V2EX  ›  PHP

关于 PHP 的 yield 的一个奇怪的问题

  •  
  •   rockyliang · 2021-06-22 11:36:26 +08:00 · 1854 次点击
    这是一个创建于 1010 天前的主题,其中的信息可能已经有所发展或是发生改变。

    最近在学习 PHP yield 相关的知识,遇到了一个搞不懂的问题,直接上代码:

    function gen() {
        for ($i = 0; $i < 3; $i++) {
            echo "For index:$i\n";
            $tmp = (yield $i);
        }
    }
    
    $gen = gen();
    foreach ($gen as $val) {
        echo "Generator return:$val\n";
    }
    echo "Finish\n";
    

    上面这段代码会输出:

    For index:0
    Generator return:0
    For index:1
    Generator return:1
    For index:2
    Generator return:2
    Finish
    

    但是,只要在代码里加多一句send的代码,如下:

    function gen() {
        for ($i = 0; $i < 3; $i++) {
            echo "For index:$i\n";
            $tmp = (yield $i);
        }
    }
    
    $gen = gen();
    foreach ($gen as $val) {
        echo "Generator return:$val\n";
        $gen->send(++$val); // 这句是新加的代码
    }
    echo "Finish\n";
    

    然后输出就会变成(相比原输出,少了一行"Generator return:1"):

    For index:0
    Generator return:0
    For index:1
    For index:2
    Generator return:2
    Finish
    

    问题:在这个例子里,为什么加了一句 send 后,输出内容就改变了?

    3 条回复    2021-06-22 22:58:11 +08:00
    ykw
        1
    ykw  
       2021-06-22 13:30:08 +08:00   ❤️ 1
    如果在调用此方法时生成器不在 yield 表达式,**则在发送值之前首先让它前进到下一个 yield 表达式**。因此,没有必要使用 Generator::next() 调用来“准备”PHP 生成器。

    `send()` 就迭代了一次。
    rockyliang
        2
    rockyliang  
    OP
       2021-06-22 13:57:30 +08:00
    @ykw 好吧,还真是这样,调用 send()后,生成器继续执行,进入到了第二轮循环($i = 1 ),然后 1 作为 send()的返回值返回给了外部,外部没有打印出来,所以输出内容就少了一行。明白了,谢谢你:)
    weirdo
        3
    weirdo  
       2021-06-22 22:58:11 +08:00
    send() ,就直接跑到下一次 yield 了呀
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   1049 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 29ms · UTC 22:34 · PVG 06:34 · LAX 15:34 · JFK 18:34
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.