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