Php norewindicator何时回放内部迭代器?

Php norewindicator何时回放内部迭代器?,php,iterator,spl,Php,Iterator,Spl,当PHP的norewindicator倒带时,它的名字非常清楚:从不 但有时,特别是当从它延伸出来时,我会问自己:它曾经倒转过吗?它倒带一次吗?因此,如果我需要它,我是否需要实现(第一次)倒带,因为一些可遍历的可能需要它 我特别想知道这里的内部迭代器,因此norewindicator类将其构造函数作为参数 例如: $iterator = new SomeIterator(); // implements Iterator $noRewind = new NoRewindIterator($ite

当PHP的
norewindicator
倒带时,它的名字非常清楚:从不

但有时,特别是当从它延伸出来时,我会问自己:它曾经倒转过吗?它倒带一次吗?因此,如果我需要它,我是否需要实现(第一次)倒带,因为一些可遍历的
可能需要它

我特别想知道这里的内部迭代器,因此
norewindicator
类将其构造函数作为参数

例如:

$iterator = new SomeIterator(); // implements Iterator
$noRewind = new NoRewindIterator($iterator);
foreach ($noRewind as $value) {
    break;
}
/**
 * Class OneTimeRewindIterator
 */
class OneTimeRewindIterator extends NoRewindIterator
{
    private $didRewind = FALSE;

    public function rewind() {
        if ($this->didRewind) return;

        $this->didRewind = TRUE;
        $this->getInnerIterator()->rewind();
    }
}

从现在开始使用
$noRewind
时,是否永远不会调用
$iterator->revind()
?或者在第一次调用
$noRewind->revind()
时(例如,在示例中的第一个
foreach
中),它会被调用一次。或者可能是在构造上?

如仅通过类的名称(
norewindicator
),具体如下:

NOREWINDIATORT-此迭代器无法重绕

对于具体方法:

NOREWINDIATOR::rewind()-防止在内部迭代器上执行rewind操作

这意味着,
Iterator::rewind()
方法不会传递给内部迭代器。测试也显示了这一点,这里是我一直在运行的一个简单的迭代器(不是PHP的一部分的所有迭代器的代码都在下面的代码中):

在这段代码中,调试迭代器动态打印(回显)迭代信息:

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()
从未被调用

这也有道理,原因与相关问题中给出的相同:。
NoRewindIterator
扩展自
iteratoritator
,与它的父类不同,
getInnerIterator()
方法返回一个
迭代器,而不是一个
可遍历的

此更改允许您在需要时初始化倒带:

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
了解这些细节后,就可以创建一个
onetimerewinditor
,例如:

$iterator = new SomeIterator(); // implements Iterator
$noRewind = new NoRewindIterator($iterator);
foreach ($noRewind as $value) {
    break;
}
/**
 * Class OneTimeRewindIterator
 */
class OneTimeRewindIterator extends NoRewindIterator
{
    private $didRewind = FALSE;

    public function rewind() {
        if ($this->didRewind) return;

        $this->didRewind = TRUE;
        $this->getInnerIterator()->rewind();
    }
}

与单独使用类的名称(
norewindicator
)一样,以下措辞是具体的:

NOREWINDIATORT-此迭代器无法重绕

对于具体方法:

NOREWINDIATOR::rewind()-防止在内部迭代器上执行rewind操作

这意味着,
Iterator::rewind()
方法不会传递给内部迭代器。测试也显示了这一点,这里是我一直在运行的一个简单的迭代器(不是PHP的一部分的所有迭代器的代码都在下面的代码中):

在这段代码中,调试迭代器动态打印(回显)迭代信息:

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()
从未被调用

这也有道理,原因与相关问题中给出的相同:。
NoRewindIterator
扩展自
iteratoritator
,与它的父类不同,
getInnerIterator()
方法返回一个
迭代器,而不是一个
可遍历的

此更改允许您在需要时初始化倒带:

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
了解这些细节后,就可以创建一个
onetimerewinditor
,例如:

$iterator = new SomeIterator(); // implements Iterator
$noRewind = new NoRewindIterator($iterator);
foreach ($noRewind as $value) {
    break;
}
/**
 * Class OneTimeRewindIterator
 */
class OneTimeRewindIterator extends NoRewindIterator
{
    private $didRewind = FALSE;

    public function rewind() {
        if ($this->didRewind) return;

        $this->didRewind = TRUE;
        $this->getInnerIterator()->rewind();
    }
}

norewindicator
在某些情况下可以进行某种程度的回放

例如,当您在室外使用“继续循环”时:

<?php
$iterator = new NoRewindIterator(new ArrayIterator([1, 2, 3, 4]));
foreach ([1, 2, 3, 4] as $a) {
    foreach ($iterator as $b) {
        echo "$a\t$b\n";
        continue 2;
    }
}
用一个简单的
break
交换
continue 2
不会改变任何事情

<?php
$iterator = new \NoRewindIterator(new \ArrayIterator([1, 2, 3, 4]));

$array = [1, 2, 3, 4];

foreach ($array as $a) {
    foreach ($iterator as $b) {
        echo "$a\t$b\n";
        break;
    }
}

Norewindicator
在某些情况下可以进行某种程度的回放

例如,当您在室外使用“继续循环”时:

<?php
$iterator = new NoRewindIterator(new ArrayIterator([1, 2, 3, 4]));
foreach ([1, 2, 3, 4] as $a) {
    foreach ($iterator as $b) {
        echo "$a\t$b\n";
        continue 2;
    }
}
用一个简单的
break
交换
continue 2
不会改变任何事情

<?php
$iterator = new \NoRewindIterator(new \ArrayIterator([1, 2, 3, 4]));

$array = [1, 2, 3, 4];

foreach ($array as $a) {
    foreach ($iterator as $b) {
        echo "$a\t$b\n";
        break;
    }
}
还有这个:还有这个: