NoRewindIterator何时回退内部迭代器? [英] When does the NoRewindIterator rewind the inner Iterator?

查看:137
本文介绍了NoRewindIterator何时回退内部迭代器?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

通过它的名字,当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 在示例中)。或者也许在构造?

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆