博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
理解php中的yield
阅读量:5277 次
发布时间:2019-06-14

本文共 2071 字,大约阅读时间需要 6 分钟。

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既是表达式又是语句的理解--------

=10) { $gen->send('stop'); } $i++; }?>

 

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

转载于:https://www.cnblogs.com/phptea/p/5629510.html

你可能感兴趣的文章
对SPI、IIC、IIS、UART、CAN、SDIO、GPIO的解释
查看>>
Thymeleaf模板格式化LocalDatetime时间格式
查看>>
网卡最大传输单位MTU和巨型帧(Jumbo frame)设置
查看>>
jquery bind()方法与live()方法的区别
查看>>
linux安装FFMpeg
查看>>
Python3之format
查看>>
【转】HTML5 API——无刷新更新地址 history.pushState/replaceState 方法
查看>>
USACO / Magic Squares(经典BFS+Cantor展开hash)
查看>>
POJ 2115 C Looooops (扩展欧几里德解同余方程 Ax = B(mod C) )
查看>>
c/c++优秀博文
查看>>
emms指令在MMX指令中的作用
查看>>
Android NDK 交叉编译C++代码生成.so共享库详细步骤
查看>>
1282 回文数猜想
查看>>
notifyDataSetChanged() 动态更新ListView 通过 Handler AsyncTask两种方式
查看>>
poj 1151
查看>>
利用深度学习的点云语义分割(一)
查看>>
hadoop安装笔记
查看>>
vim退出后终端保留 退出前的内容
查看>>
流程预览 ?
查看>>
git中的基本命令
查看>>