$arrayIter = new ArrayIterator( array(1, 2) );
$iterIter = new IteratorIterator($arrayIter);
var_dump($iterIter->valid()); //false
var_dump($arrayIter->valid()); //true
如果我首先调用 $ iterIter-> rewind(),则 $ iterIter-> valid()为true。我很好奇为什么要调用rewind()。我想它有充分的理由,但我希望它只是在内部迭代器处于的任何状态下开始迭代,并在开始迭代之前将其作为倒带选项。
调用next()似乎也将其置于“有效”状态(虽然它前进到下一个位置,表明它之前位于第一个位置)。
$arrayIter = new ArrayIterator(array(1,2));
$iterIter = new IteratorIterator($arrayIter);
$iterIter->next();
var_dump($iterIter->valid());
同样,我很好奇为什么我需要调用rewind(),尽管内部迭代器处于有效状态。
答案 0 :(得分:5)
使用新的迭代器,位置没有初始化,只是出于性能原因,你可以将迭代器堆叠在其他迭代器之上,如果所有这些迭代器在构造期间都会倒带会对性能产生影响,另外一些迭代器可能会改变它们的执行构造函数后的第一个值 - 对于迭代器来说是未知的。
迭代器通常由foreach()执行,它首先执行倒带()...
答案 1 :(得分:2)
在扩展IteratorIterator
类以实现整个迭代器接口和/或创建迭代器的装饰器的同时,我也遇到过这种情况。
该装饰器已经是问题的解决方案,它只需要实现缺少的功能来消除不一致性。无需自动倒带:
class IteratorDecorator extends IteratorIterator
{
public function valid()
{
return $this->getInnerIterator()->valid();
}
}
示例:如果您的Iterator
对象默认有效,例如ArrayIterator
:
$it = new ArrayIterator(array(1));
var_dump($it->valid()); # bool(true)
$itit = new IteratorIterator($it);
var_dump($itit->valid()); # bool(false)
这显示了IteratorIterator
实现的不一致性,IteratorIterator
对象未正确反映内部ArrayIterator
的状态。使用IteratorDecorator
可以治愈这个:
$decor = new IteratorDecorator($it);
var_dump($decor->valid()); # bool(true)
如果您已经跟进到此处,那么您可能需要考虑另一个特殊情况:如果您不需要使用内部迭代器rewind
,则可以使用{{1}这也返回了有效性:
NoRewindIterator
将约翰内斯的“无自动倒回”参数考虑在内,这是有道理的,因为$noretit = new NoRewindIterator($it);
var_dump($noretit->valid()); # bool(true)
期望迭代器不应该被重新整理并正确显示内部迭代器的有效性。
但正如NoRewindIterator
所示,我不会进行任何类型的自动倒回以消除不一致。
答案 2 :(得分:0)
就像@johannes所说的那样,位置没有在IteratorIterator
中初始化,因此在它运行任何其他方法或者与foreach()一起使用之前它是无效的
尝试
var_dump( $iterIter->current() ); // NULL
var_dump( $iterIter->getInnerIterator()->current() ); // 1
还
$iterIter->rewind();
var_dump( $iterIter->current() ); // 1
var_dump( $iterIter->getInnerIterator()->->current() ); // 1
还要注意在unitiliazed IteratorIterator上:
$iterIter->next(); // 2
var_dump( $iterIter->current()) ; // 2 (from NULL to 2)
var_dump( $iterIter->getInnerIterator()->current() ); // 2
请注意,您的代码段中的$arrayIter
与$iterIter->getInnerIterator()
相同。
希望能有所启发。