php iterator有什么用,对php中IteratorIterator的理解(代码示例)

本篇文章给大家带来的内容是关于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产生任何影响。

代码演示<?php

namespace 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__ . '
';

reset($this->dates);

}

public function valid()

{

echo 'call ' . __METHOD__ . '
';

if ($this->position >= count($this->dates)) {

# code...

return false;

}

return true;

}

public function current()

{

echo 'call ' . __METHOD__ . '
';

return $this->dates[$this->position];

}

public function key()

{

echo 'call ' . __METHOD__ . '
';

return $this->position;

}

public function next()

{

echo 'call ' . __METHOD__ . '
';

++$this->position;

}}class OuterIterator extends \IteratorIterator{

function rewind()

{

echo __METHOD__ . '
';

return parent::rewind();

}

function valid()

{

echo __METHOD__ . '
';

return parent::valid();

}

function current()

{

echo __METHOD__ . '
';

return parent::current() . '_suffix';

}

function key()

{

echo __METHOD__ . '
';

return parent::key() ;

}

function next()

{

echo __METHOD__ . '
';

return parent::next() ;

}

function getInnerIterator()

{

echo __METHOD__ . '
';

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 . '


';}

运行结果:

young\OuterIterator::rewindcall young\InnerIterator::rewind

call young\InnerIterator::valid

call young\InnerIterator::current

call young\InnerIterator::keyyoung\OuterIterator::valid

young\OuterIterator::current

young\OuterIterator::key

0=>2018-10-01_suffix

young\OuterIterator::nextcall young\InnerIterator::next

call young\InnerIterator::valid

call young\InnerIterator::current

call young\InnerIterator::keyyoung\OuterIterator::valid

young\OuterIterator::current

young\OuterIterator::key

1=>2018-10-02_suffix

young\OuterIterator::nextcall young\InnerIterator::next

call young\InnerIterator::validyoung\OuterIterator::valid

object(young\InnerIterator)#1 (2) {

[“dates”:“young\InnerIterator”:private]=> array(2) { [0]=>

string(10) “2018-10-01” [1]=> string(10) “2018-10-02” }

[“position”:“young\InnerIterator”:private]=> int(2) }

结果分析

Outer的每次迭代会先调用自己的方法,然后转发给Inner。

Outer内部方法的返回值都是基于Inner的相对于方法的返回。

你可以在Outer内方法对Inner的返回值做逻辑处理。

当Inner的valid返回false的时候,外层的Outer也将停止迭代。

Outer内的方法对返回值的修改并不会影响Inner。

Outer内的方法在迭代过程中并不会执行getInnerIterator方法,它只是一个获取Inner方法的调用接口。

一点补充

之前在网上翻阅资料时会看到这样的疑惑//假如这里还是使用了上面的两个类代码

namespace 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操作,但是这个操作在第二遍压根就没用~~~

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在 C++ ,迭代器(iterator)是一个对象,它能够遍历容器(如 vector、list、map 等)的元素,类似于指针。通过迭代器,我们可以在不知道容器内部实现细节的情况下,访问容器的元素。具体来说,迭代器提供了以下功能: 1. 遍历容器的元素:使用迭代器可以轻松地遍历容器的元素,从而进行查询、修改等操作。 2. 访问容器的元素:通过迭代器,可以访问容器的元素。 3. 定位元素位置:迭代器可以用于定位容器特定元素的位置,从而进行删除、插入等操作。 4. 提供算法支持:STL 的很多算法(如 sort、find 等)都是通过迭代器实现的。 下面是一个使用迭代器遍历 vector 容器的示例代码: ```c++ #include <iostream> #include <vector> using namespace std; int main() { vector<int> vec; // 向 vector 容器添加元素 vec.push_back(10); vec.push_back(20); vec.push_back(30); // 使用迭代器遍历 vector 容器的元素 vector<int>::iterator iter; for (iter = vec.begin(); iter != vec.end(); iter++) { cout << *iter << " "; } return 0; } ``` 上述代码,我们首先定义了一个 int 类型的 vector 容器 vec,然后使用 push_back() 函数向容器添加了三个元素。接着,我们使用迭代器 iter 遍历容器的元素,并打印输出。运行代码,输出结果如下: ``` 10 20 30 ``` 可以看到,使用迭代器可以轻松地遍历 vector 容器的元素,从而进行查询、修改等操作。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值