预定义接口(Predefined Interfaces)
Traversable
Iterator
IteratorAggregate(聚合式迭代器)接口
Generator 生成器
ArrayAccess
Serializable
Closure
IteratorAggregate(聚合式迭代器)接口
接口摘要
IteratorAggregate extends Traversable {
/* 方法 */
abstract public Traversable getIterator ( void )
}个接口实现了一个功能——创建外部迭代器,具体怎么理解呢,当我们使用foreach对对象进行便遍历的时候,如果没有继承IteratorAggregate接口,遍历的是对象中所有的public属性(只能是public $var这种形式)。要是继承了IteratorAggregate,会使用类中实现的getIterator方法返回的对象,这里要注意返回的一定要是一个Traversable对象或者扩展自Traversable的对象,否则会抛出异常
示例:
ArrayIterator 对数组进行了Iterator封装
class My{
private $_data = [
'a' => '燕睿涛',
'b' => 'yanruitao',
'c' => 'LULU',
];
public function getIterator()
{
return new ArrayIterator($this->_data);
}
}
$obj = new My;
foreach ($obj as $key => $value) {
echo "$key => $value\n";
}
//输出结果为空改造
结果:
示例:
Countable 的目的是能够使用php count函数来统计日志的行数
Iterator 迭代器需要实现current() key() next() rewind() valid()方法
foreach 之前,先rewind() ,将遍历的指针重置到遍历的开头,调用next() 将指针移动到下一个位置,current() 则可以获得当前指针指向数据,每次循环都会调用valid()方法,如果返回false,则证明遍历结束
a.log
思考:为什么不用 file() 函数读到数组里面再遍历?
有可能会出现一下错误(内存不够用):
解决办法:
用生成器!
生成器(Generator)
生成器提供了一种更简单的可实现 Iterator 同样功能的方法。
你可以通过生成器逐条产生(yield)供 foreach 遍历的数据,而且不需要事先在内存中建立整个数组。
生成器像一个函数,但是使用关键词 yield 返回数据。
Generator 是 Traversable 的子类
示例:
进一步key=>value形式
IteratorAggregate 与 yield 的结合示例
getIterator 需要返回一个Traversable 对象, 生成器yield 就是一个Traversable的对象的子类
总结
实现了 Traversable 的对象都可以通过 foreach 实现遍历;
生成器函数实现 foreach 更简单,适用于简单的数据和逻辑;
Iterator 实现 foreach 可定制性更高,适用于较复杂的逻辑;
IteratorAggregate 可返回一个外部迭代器,可对数据本身及相关逻辑做更统一的封装。
资料
Last updated
Was this helpful?