php 迭代器与生成器使用情景,php 迭代器与和生成器

php有很多功能强大的接口,其中ArrayAccess 与 Iterator 的配合使用可以让对象与数组一样有着灵活的访问性。

当然,用ArrayAccess 与 Iterator 配合可以用来对付数组,但还有一个更好的办法同则SPL 提供的ArrayIterator

原因就是 :

ArrayIterator implement ArrayAccess, SeekableIterator, Countable, Searializable {}

而接下来要介绍的则是Iterator的更高一层用法。

与Iterator有关的函数先记录下

iterator_to_array() 把迭代器中的元素转换成数组

IteratorAggregate::getIterator() 调用一个外部迭代器

ArrayIterator

Iteartor_count() 等等

而php在使用Iterator接口则是迭代器模式的一种实现。在这里,其中的概念客户端(实现迭代过程)、迭代器、具体迭代器则会别对应于,foreach() , 继承于iterator接口的具体类和需要遍历的数组或集合。

而生成器,则是建立在理解迭代器的基础之上。

php中的生成器,可以叫做迭代生成器,因为它就是一个不可new的类,同时继承Iterator,且多了一个send() 与 生成器通信

它的实现则是通过yield关键字,或语句,或表达式,其工作方式则是,使用yield的结构体就是一个生成生成器类,当执行到yield

时,则中断该生成器,并存储其状态,当再次执行(foreach 或 while等循环结构) , 则会恢复其状态,并直到再次遇到yield

复制代码

function gen() {

$ret = (yield 'yield1');

var_dump($ret);

$ret = (yield 'yield2');

var_dump($ret);

}

$gen = gen();

var_dump($gen->current()); // output:string(6) "yield1" 当该生成器形成的时候

//rewind()就已经隐式的执行,即生成就已经到第一个yield中断了

var_dump($gen->send('ret1')); // output:string(4) "ret1" (the first var_dump in gen)

// 这时,send()则做了它该做的,恢复中断,把值(ret1)传入yield,并返回yield(ret1), 直到再遇到yield ,无则返回null

// output:string(6) "yield2" (the var_dump of the ->send() return value)

// 这时执行到$ret = (yields 'yield2'); 时则中磁芯,并把yield表达式的值返回,

//此时为 yield2 ,若没有 后面的 ‘yield2’, 则会返回null

var_dump($gen->send('ret2')); //output:string(6) "yield2" (the var_dump of the ->send() return value)

// output:null

// 这时send()执行的时候 ,并没有下一个yield则返回的是null,而其恢复执行后在函数体内有一个var_dump(),所以会有output

其实,由上面的实例可总结出两点 ,

一是,初始化生成器时则已经到了一个yield,形成了中断,

二是,send 的执行实际上是,先next() , 再vaild() , 不能过则return null, 通过则current() ,返回,若是yield 后没有“默认”($ret = (yield 'default');),

则返回的是null,再进行中断,直至再次恢复。

理解了它是如何工作的,则出现了一个实际的问题,它有什么用呢?

生成器的高级使用出现在“在php中使用协程实现多任务调度”这一主题中,该主题偏难,而我对它的理解也只是到了简单的任务调度这一块

而更高级的内容,再慢慢了解。

为什么它能完成任务的调度呢?关于这一点可类比操作系统中的程序中断,在那里,中断的作用则就是为了任务调度。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值