/首页
/开源
/关于
老旧话题:yield是个什么玩意(上)
发表@2018-09-13 09:15:22
更新@2023-01-21 22:47:40
其实,我并不是因为迭代或者生成器或者研究PHP手册才认识的yield,要不是协程,我到现在也不知道PHP中还有yield这么个鬼东西。人家这个东西是从PHP 5.5就开始引入了,官方名称叫做生成器。你要说为什么5.5年代的东西,现在才拿出来。我还想问你哟,PHP 5.3就有了的namespace为毛到最近这几年才开始正式投产。 那么,问题来了,这东西到底是有何用? 先来感受一个问题,给你100Kb的内存(是的,你没有看错,就是100Kb),然后让你迭代输出一个从1开始一直到10000的数组,步进为1。 愈先迭代数组,必先创造数组。 所以,脑门一拍,代码一坨如下: ```php valid() ){ echo $generator->current().PHP_EOL; $generator->next(); } ``` 运行结果如下所示: ![](https://ti-node.com/static/upload/6426627373801668608) 重点来了:这个yield_range函数似乎能够记住它上一次运行到哪儿了,上一次运行的结果是什么,然后紧接着在下一次运行的时候继续从上次终止的地方继续开始。这不是普通的PHP函数可以做得到的! 我们知道,操作系统在调度进程的时候,会触发一个叫做“进程上下文切换”的概念。比如CPU从进程A调度给进程B了,那么当再次从进程B调度给进程A的时候,当初进程A运行到哪儿了、临时的数据结果是什么都是需要被还原的,不然,一切都要从头,那就要出大问题了。而,这个yield关键字,似乎在用户态(非系统内核级)就可以实现这个概念。所以说,用yield搞迭代,怕是真的很没出息的一件事,它能做的太多。 紧接着,我们需要认识一个生成器对象的一个方法,叫做send,简单看下下面这坨代码: ```php send( $generator->current() * 10 ); ``` 运行结果如图所示: ![](https://ti-node.com/static/upload/6426631112352595969) send方法可以修改yield的返回值,但是,你也不能想当然,比如下面这坨代码,你们以为运行结果是什么样呢? ```php send( $generator->current() * 10 ); } ``` 本来以为运行结果是类似于这样的: ```php