对php中IteratorIterator的理解(代码示例)
内容导读
收集整理的这篇技术教程文章主要介绍了对php中IteratorIterator的理解(代码示例),小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含4654字,纯文字阅读大概需要7分钟。
内容图文
本篇文章给大家带来的内容是关于php中IteratorIterator的理解(代码示例),有一定的参考价值,有需要的朋友可以参考一下,希望对你有所帮助。
php之IteratorIterator个人理解
最近有重新开始捣鼓laravel的源码了,一年多没用实在是忘的差不多了,每次看都会从中学到很多,不懂就赶紧查手册。看到加载配置文件的部分(config/*.php),代码中大量使用spl类库和接口,今天就来扯一下IteratorIterator类,网上资料太少了,加上本人也不是怎么聪明,搞了好几天才有点眉目,以下是对它的个人理解。
IteratorIterator简介
IteratorIterator是一个迭代器包装器,当然它本身也是迭代器。它(假定它叫Outer)在实例化时必须传入一个实现了Traversable接口类型的迭代器实例(假定它叫Inner),当然你可以通过Outer的getInnerIterator方法获取到这个传入的迭代器参数Inner。你可以通过Outer的rewind(),next(),valid(),current()和key()方法对内部迭代器Inner进行处理。
重点理解
在遍历Outer的过程中,Outer只是将rewind(),next(),valid(),current()和key()的任何调用转发给内部迭代器Inner。
Outer可以对转发返回的结果进行包装,但这并不会对Inner产生任何影响。
代码演示
<?phpnamespace young;class InnerIterator implements Iterator{ private $dates; private $position; public function __construct($dates = []) { $this->dates = $dates; $this->position = 0; } public function rewind() { echo 'call ' . __METHOD__ . '<br>'; reset($this->dates); } public function valid() { echo 'call ' . __METHOD__ . '<br>'; if ($this->position >= count($this->dates)) { # code... return false; } return true; } public function current() { echo 'call ' . __METHOD__ . '<br>'; return $this->dates[$this->position]; } public function key() { echo 'call ' . __METHOD__ . '<br>'; return $this->position; } public function next() { echo 'call ' . __METHOD__ . '<br>'; ++$this->position; }}class OuterIterator extends IteratorIterator{ function rewind() { echo __METHOD__ . '<br>'; return parent::rewind(); } function valid() { echo __METHOD__ . '<br>'; return parent::valid(); } function current() { echo __METHOD__ . '<br>'; return parent::current() . '_suffix'; } function key() { echo __METHOD__ . '<br>'; return parent::key() ; } function next() { echo __METHOD__ . '<br>'; return parent::next() ; } function getInnerIterator() { echo __METHOD__ . '<br>'; return parent::getInnerIterator(); }}$tmpArr = array( '2018-10-01', '2018-10-02', //'2018-10-03',);$inner = new InnerIterator($tmpArr);$outer = new OuterIterator($inner);foreach ($outer as $key => $value) { # code... echo $key , '=>' , $value . '<hr>';}
运行结果:
youngOuterIterator::rewind
call youngInnerIterator::rewindcall youngInnerIterator::validcall youngInnerIterator::currentcall youngInnerIterator::key
youngOuterIterator::validyoungOuterIterator::currentyoungOuterIterator::key0=>2018-10-01_suffixyoungOuterIterator::next
call youngInnerIterator::nextcall youngInnerIterator::validcall youngInnerIterator::currentcall youngInnerIterator::key
youngOuterIterator::validyoungOuterIterator::currentyoungOuterIterator::key1=>2018-10-02_suffixyoungOuterIterator::next
call youngInnerIterator::nextcall youngInnerIterator::valid
youngOuterIterator::valid object(youngInnerIterator)#1 (2) { [“dates”:“youngInnerIterator”:private]=> array(2) { [0]=> string(10) “2018-10-01” [1]=> string(10) “2018-10-02” } [“position”:“youngInnerIterator”:private]=> int(2) }
结果分析
Outer的每次迭代会先调用自己的方法,然后转发给Inner。
Outer内部方法的返回值都是基于Inner的相对于方法的返回。
你可以在Outer内方法对Inner的返回值做逻辑处理。
当Inner的valid返回false的时候,外层的Outer也将停止迭代。
Outer内的方法对返回值的修改并不会影响Inner。
Outer内的方法在迭代过程中并不会执行getInnerIterator方法,它只是一个获取Inner方法的调用接口。
一点补充
之前在网上翻阅资料时会看到这样的疑惑
//假如这里还是使用了上面的两个类代码<?phpnamespace young;class InnerIterator implements Iterator{ //code 这里的代码假如和上面的一样}class OuterIterator extends IteratorIterator{ //code 这里的代码假如和上面的一样}$outer->valid(); //false$outer->current(); // _suffix 问题一$outer->rewind(); $outer->valid(); //true$outer->current(); //2018-10-01_suffix$outer->next()$outer->rewind();$outer->current(); //2018-10-02_suffix 问题二
这里有两个问题,
问题一,为什么当前current没值,valid为false
问题二,问什么next后rewind之后,current是第二个值
从上面的运行结果可知,$outer不执行rewind,$inner也不会执行,所以valid返回false,current为null,_suffix只是自己拼接上的。
第二个问题也是很奇怪的,也是刚刚发现的,$inner的指针只要前进了,就回不去了,也就是说 $inner的position属性在第一次next之后变成1了,即使你rewind,position还是1,这个有点蒙蔽啊。。。
所以如果你进行了$outer的遍历操作,第二遍是没值输出的,即使第二遍也执行了rewind操作,但是这个操作在第二遍压根就没用~~~
以上就是对php中IteratorIterator的理解(代码示例)的详细内容,更多请关注Gxl网其它相关文章!
内容总结
以上是为您收集整理的对php中IteratorIterator的理解(代码示例)全部内容,希望文章能够帮你解决对php中IteratorIterator的理解(代码示例)所遇到的程序开发问题。 如果觉得技术教程内容还不错,欢迎将网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。