Php 为什么我必须倒带迭代器

Php 为什么我必须倒带迭代器,php,iterator,spl,Php,Iterator,Spl,如果我首先调用$iterIter->revind(),那么$iterIter->valid()为true。我很好奇为什么需要调用revind()。我想这是有充分理由的,但我希望它只是在内部迭代器处于的任何状态下开始迭代,并在开始迭代之前将其作为一个倒带选项 调用next()似乎也会使它处于“有效”状态(尽管它会前进到下一个位置,这表明它以前在第一个位置) 同样,我很好奇为什么我需要调用rewind(),尽管内部迭代器处于有效状态。对于新的迭代器,位置没有初始化,只是出于性能原因,您可以将迭代器堆

如果我首先调用$iterIter->revind(),那么$iterIter->valid()为true。我很好奇为什么需要调用revind()。我想这是有充分理由的,但我希望它只是在内部迭代器处于的任何状态下开始迭代,并在开始迭代之前将其作为一个倒带选项

调用next()似乎也会使它处于“有效”状态(尽管它会前进到下一个位置,这表明它以前在第一个位置)


同样,我很好奇为什么我需要调用rewind(),尽管内部迭代器处于有效状态。

对于新的迭代器,位置没有初始化,只是出于性能原因,您可以将迭代器堆叠在其他迭代器之上,如果所有迭代器在构造期间都会倒转,则会对性能产生一些影响,此外,一些迭代器可能会在构造函数执行后更改它们的第一个值,这对于后面的迭代器来说是未知的


迭代器通常由foreach()执行,foreach()首先执行倒带()。

如@johannes所说,迭代器中的位置未初始化,因此在对其运行任何其他方法或与foreach()一起使用之前,该位置无效

尽力

$arrayIter = new ArrayIterator(array(1,2));
$iterIter = new IteratorIterator($arrayIter);

$iterIter->next();
var_dump($iterIter->valid()); 
而且

var_dump( $iterIter->current() ); // NULL
var_dump( $iterIter->getInnerIterator()->current() ); // 1
还要注意,在联合迭代器上:

$iterIter->rewind();
var_dump( $iterIter->current() ); // 1
var_dump( $iterIter->getInnerIterator()->->current() );  // 1
请注意,代码段中的
$arrayIter
$iterIter->getInnerIterator()
相同


希望这能有所启发。

在扩展
迭代器
类以避免实现整个迭代器接口和/或创建迭代器的装饰器时,我也遇到了这个问题

该装饰器已经是问题的解决方案,它只需要实现缺失的功能来消除不一致性。无需自动倒带:

$iterIter->next(); // 2
var_dump( $iterIter->current()) ; // 2 (from NULL to 2)
var_dump( $iterIter->getInnerIterator()->current() );  // 2
示例:如果您有一个默认有效的
迭代器
对象,例如
数组迭代器

class IteratorDecorator extends IteratorIterator
{
    public function valid()
    {
        return $this->getInnerIterator()->valid();
    }
}
这显示了
迭代器
实现的不一致性。好了,
迭代器
对象不能正确反映内部
数组迭代器
的状态。使用
IteratorDecorator
可以解决以下问题:

$it = new ArrayIterator(array(1));
var_dump($it->valid());             # bool(true)

$itit = new IteratorIterator($it);
var_dump($itit->valid());           # bool(false)
如果您一直跟踪到这里,这里是另一个您可能需要考虑的特殊情况:如果您不需要使用内部迭代器进行
倒带
,您可以使用
NoRewindIterator
,它也会返回正确的有效性:

$decor = new IteratorDecorator($it);
var_dump($decor->valid());          # bool(true)
考虑到Johannes的“no auto rewind”参数,这是有意义的,因为
norewindicator
希望迭代器不应该被倒带,并正确显示内部迭代器的有效性


但是正如迭代器Decorator所示,我没有做任何类型的自动倒带来消除不一致性。

我怀疑这样的事情。我已经认为自动倒带是不可取的,但不明白为什么需要倒带。你能举出一个迭代器改变其第一个值的例子吗?简单的例子:$ai=newappenditerator()$ii=新迭代器($ai)$ai->append(新的ArrayIterator(数组(1,2,3));在前面的小示例中:在创建$ai的过程中倒带是没有用的,因为没有值。在创建$ii的过程中也没有效果(除了浪费的CPU周期)。append()期间这可能是错误的,因为在迭代过程中可能会附加迭代器。好的。我不知道内部迭代器中的值被缓存到外部迭代器中。似乎在调用rewind()和next()时都会检索到这些值。我以为在当前()时会从内部迭代器中检索到这些值我以前看过这个,这让我误入歧途
$decor = new IteratorDecorator($it);
var_dump($decor->valid());          # bool(true)
$noretit = new NoRewindIterator($it);
var_dump($noretit->valid());        # bool(true)