来源:不言 发布时间:2018-10-26 17:07:51 阅读量:618
最近有重新开始捣鼓laravel的源码了,一年多没用实在是忘的差不多了,每次看都会从中学到很多,不懂就赶紧查手册。看到加载配置文件的部分(config/*.php),代码中大量使用spl类库和接口,今天就来扯一下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产生任何影响。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 |
|
1 |
|
1 2 3 4 |
|
1 2 3 4 5 |
|
1 2 3 4 |
|
1 2 3 4 5 |
|
1 2 |
|
1 2 3 4 5 |
|
Outer的每次迭代会先调用自己的方法,然后转发给Inner。
Outer内部方法的返回值都是基于Inner的相对于方法的返回。
你可以在Outer内方法对Inner的返回值做逻辑处理。
当Inner的valid返回false的时候,外层的Outer也将停止迭代。
Outer内的方法对返回值的修改并不会影响Inner。
Outer内的方法在迭代过程中并不会执行getInnerIterator方法,它只是一个获取Inner方法的调用接口。
之前在网上翻阅资料时会看到这样的疑惑
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
|
这里有两个问题,
问题一,为什么当前current没值,valid为false
问题二,问什么next后rewind之后,current是第二个值
从上面的运行结果可知,$outer不执行rewind,$inner也不会执行,所以valid返回false,current为null,_suffix只是自己拼接上的。
第二个问题也是很奇怪的,也是刚刚发现的,$inner的指针只要前进了,就回不去了,也就是说 $inner的position属性在第一次next之后变成1了,即使你rewind,position还是1,这个有点蒙蔽啊。。。
所以如果你进行了$outer的遍历操作,第二遍是没值输出的,即使第二遍也执行了rewind操作,但是这个操作在第二遍压根就没用~~~