NoRewindIterator何时回退内部迭代器? [英] When does the NoRewindIterator rewind the inner Iterator?
问题描述
通过它的名字,当PHP的 NoRewindIterator
倒带时,非常清楚:从不。
By its name it is perfectly clear when PHP's NoRewindIterator
rewinds: never.
但有时,尤其是。从它延伸时,我问自己:它是否会倒带?它倒带一次吗?所以,如果我需要它,我是否需要实现(第一次)倒带,因为某些 Traversable
可能需要它?
But sometimes, esp. when extending from it, I ask myself: Does it ever rewind? Does it rewind once? So if I need it, do I need to implement the (first) rewind as some Traversable
might require it?
我特别想知道这里的内部迭代器,所以 Iterator
NoRewindIterator
类作为参数及其构造函数。
I specifically wonder about the inner iterator here, so the Iterator
the NoRewindIterator
class takes as parameter with its constructor.
例如:
$iterator = new SomeIterator(); // implements Iterator
$noRewind = new NoRewindIterator($iterator);
foreach ($noRewind as $value) {
break;
}
将 $ iterator-> rewind()
从这里开始使用 $ noRewind
时从不调用?或者第一次调用一次 $ noRewind-> rewind()
被调用(例如在第一个 foreach $ c $内c>在示例中)。或者也许在构造?
Will $iterator->rewind()
be never called when using $noRewind
from here on? Or will it be called once for the first time $noRewind->rewind()
is invoked (e.g. within the first foreach
in the example). Or maybe on construct?
推荐答案
就像单独的类名一样( NoRewindIterator
),手册中具体说明如下:
Like by the name of the class alone (NoRewindIterator
), the manual has the following wording in specific:
NoRewindIterator - 此迭代器无法倒带。
NoRewindIterator - This iterator cannot be rewound.
对于具体方法:
NoRewindIterator :: rewind() - 防止内部迭代器上的倒带操作。
NoRewindIterator::rewind() - Prevents the rewind operation on the inner iterator.
这意味着 Iterator :: rewind()
方法不会传递给内部迭代器。测试也显示了这个,这是一个我一直在运行的简单的(所有迭代器的代码都不是PHP的一部分在 Iterator Garden ):
This implies that the Iterator::rewind()
method is not passed through to the inner iterator. Tests also show this, here is a simple one I've been running (code of all iterators not part of PHP are in the Iterator Garden):
$iterator = new RangeIterator(1, 1);
$debug = new DebugIteratorDecorator($iterator);
$noRewind = new NoRewindIterator($debug);
echo "first foreach:\n";
foreach ($noRewind as $value) {
echo "iteration value: $value\n";
}
在此代码中,调试迭代器打印(回声)迭代信息fly:
In this code, the debug-iterator prints (echoes) iteration information on the fly:
first foreach:
Iterating (RangeIterator): #0 valid()
Iterating (RangeIterator): #0 parent::valid() is TRUE
Iterating (RangeIterator): #0 current()
Iterating (RangeIterator): #0 parent::current() is 1
iteration value: 1
Iterating (RangeIterator): #1 next()
Iterating (RangeIterator): #1 after parent::next()
Iterating (RangeIterator): #1 valid()
Iterating (RangeIterator): #1 parent::valid() is FALSE
如下所示, $ iterator-> rewind()
永远不会被调用。
As this shows, $iterator->rewind()
is never called.
这也是有道理的在一个相关的问题: 为什么我必须回放IteratorIterator 。 NoRewindIterator
从 IteratorIterator
和不同扩展到它的父类 getInnerIterator()
方法返回 Iterator
而不是 Traversable
。
This also makes sense for the same reasons given in a related question: Why must I rewind IteratorIterator. The NoRewindIterator
extends from IteratorIterator
and different to it's parent class, the getInnerIterator()
method returns an Iterator
and not a Traversable
.
此更改允许您在需要时初始化倒带:
This change allows you to initialize the rewind when you need to:
echo "\n\$calling noRewind->getInnerIterator()->rewind():\n";
$noRewind->getInnerIterator()->rewind();
echo "\nsecond foreach:\n";
foreach ($noRewind as $value) {
echo "iteration value: $value\n";
}
再次显示调试输出:
$calling noRewind->getInnerIterator()->rewind():
Iterating (RangeIterator): #0 rewind()
Iterating (RangeIterator): #0 after parent::rewind()
second foreach:
Iterating (RangeIterator): #0 valid()
Iterating (RangeIterator): #0 parent::valid() is TRUE
Iterating (RangeIterator): #0 current()
Iterating (RangeIterator): #0 parent::current() is 1
iteration value: 1
Iterating (RangeIterator): #1 next()
Iterating (RangeIterator): #1 after parent::next()
Iterating (RangeIterator): #1 valid()
Iterating (RangeIterator): #1 parent::valid() is FALSE
了解这些细节后,确实允许创建一个 OneTimeRewindIterator
例如:
Knowing about these details then does allow to create a OneTimeRewindIterator
for example:
/**
* Class OneTimeRewindIterator
*/
class OneTimeRewindIterator extends NoRewindIterator
{
private $didRewind = FALSE;
public function rewind() {
if ($this->didRewind) return;
$this->didRewind = TRUE;
$this->getInnerIterator()->rewind();
}
}
这篇关于NoRewindIterator何时回退内部迭代器?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!