码迷,mamicode.com
首页 > Web开发 > 详细

理解php中的yield

时间:2016-06-30 12:41:17      阅读:149      评论:0      收藏:0      [点我收藏+]

标签:

<?php
function gen() {
    $ret = (yield ‘yield1‘);
    var_dump($ret);
    $ret = (yield ‘yield2‘);
    var_dump($ret);
}
 
$gen = gen();
var_dump($gen->current());    // string(6) "yield1"
var_dump($gen->send(‘ret1‘)); // string(4) "ret1"   (the first var_dump in gen)
                              // string(6) "yield2" (the var_dump of the ->send() return value)
var_dump($gen->send(‘ret2‘)); // string(4) "ret2"   (again from within gen)
                              // NULL               (the return value of ->send())
?>

 


上面的代码首先是调用函数gen生成一个Generator对象,然后调用这个对象的current方法返回第一个值,显然它是第一个yield语句的返回值,也就是‘yield1‘,这个时候gen函数的执行就会被中止,接着执行var_dump($g->send(‘ret1‘));。

调用$g->send(‘ret1‘),传入参数为字符串‘ret1‘,按照上面的说明,它会赋值给第一个yield表达式,也就是(yield ‘yield1‘)中的yield(注意:这个时候不包括‘yield1‘),它的值为‘ret1‘,然后会赋值给$ret,所以第二个输出‘ret1‘就是gen函数中的第一个var_dump输出的。此时对Generator对象的迭代会恢复继续执行,实际上就是调用了一次next函数,它会执行到下一个yield语句:yield ‘yield2‘,这个语句会返回‘yield2‘,它会作为$g->send(‘ret1‘)的返回值,所以函数外第二个var_dump会输出‘yield2‘。

最后再次调用send函数,这次传入的参数为字符串‘ret2‘,跟上面一样,Generator对象当前位置的元素是在gen函数的第二个yield上,所以’ret2‘会被传递给第二个yield表达式,也就是作为(yield ‘yield2‘)中的yield的值,并且会被赋值给$ret变量,然后gen函数恢复执行,它会执行gen函数中的最后一个var_dump,此时对Generator对象$g的遍历也结束了,第二个send函数的返回值为NULL,这也是函数外的最后一个var_dump的输出。

读了这么一段分析以后,你现在最大的困惑是什么呢?

我最大的困惑是为什么同一个yied关键字,它既是语句,又是表达式,而且这两种情况是同时存在的:

  1. 对于所有在generator函数中出现的yield,首先它都是语句,而跟在yield后面的任何表达式的值将作为调用generator函数的返回值,如果yield后面没有任何表达式(变量、常量都是表达式),那么它会返回NULL,这一点跟return语句一致。
  2. yield也是表达式,它的值就是send函数传过来的值(相当于一个特殊变量,只不过赋值是通过send函数进行的)。只要调用send方法,并且Generator对象的迭代并未终结,那么当前位置的yield就会得到send方法传递过来的值,这跟generator函数有没有把这个值赋值给某个变量没有任何关系。

从上面两点我们就可以看出,任何时候yield关键词都即是语句——可以为generator函数返回值,也是表达式——可以接收Generator对象发过来的值。

-------------------------分界线:上面是摘抄的,下面是自己的疑问---------------------------

讲的很好。但有点疑问就是:

在执行完gen中的var_dump之后,generator应该终止啊。但是,为什么却又恢复了,继续执行下一条yield语句呢。 我猜是因为当yield作为表达式的时候,generator并没有进行迭代。只有yield被当做了语句执行之后,generator才会终止吧。


------------再次补充:关于yield既是表达式又是语句的理解--------

<?php
    function gen() {
        for($i=1;$i<=100;$i++) {
            $cmd = (yield $i);
            if($cmd==‘stop‘) {
                return;
            }
        }
    }
    $gen = gen();
    $i=0;
    foreach($gen as $item) {
        echo $item."\n";
        if($i>=10) {
            $gen->send(‘stop‘);
        }
        $i++;
    }
?>

 

这是个很好地例子:
1、yield作为语句(类似return语句),会返回$i给调用者。
2、yield作为表达式。获取send函数传递值,赋值给$cmd。
3、实现Generator对象和generator函数的通信。这个很重要。应该能实现很多generator的交互.

理解php中的yield

标签:

原文地址:http://www.cnblogs.com/phptea/p/5629510.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!