質問

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

var_dump($iterIter->valid()); //false
var_dump($arrayIter->valid()); //true

もし私の最初の呼び出しの$ iterIter->巻き戻し()の場合、の$ iterIter->有効()のは本当です。それは巻き戻し()が呼び出されている必要があり、なぜ私は興味があります。私はそれのための十分な理由があると想像しますが、私は単にそれが内部イテレータの中で何でも状態で反復開始し、反復を開始する前に巻き戻すためのオプションとして、それを残すためにそれを期待しているだろう。

を呼び出す()も(それが第1の位置に以前だった示唆、それは次の位置に進みますが)「有効」状態に入れているようだ。次の

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

$iterIter->next();
var_dump($iterIter->valid()); 
私は内部イテレータが有効な状態であるにも関わらず、巻き戻し()を呼び出す必要があり、なぜ

繰り返しますが、私は興味があります。

役に立ちましたか?

解決

の位置が初期化されていない新鮮なイテレータでは、単にパフォーマンス上の理由のために、あなたは、さらにいくつかのイテレータは自分を変えるかもしれない、それらのすべてが建設中に巻き戻すかどういくつかのパフォーマンスへの影響があるだろう、他のイテレータの上にイテレータを積み重ねることができますコンストラクタが実行された後の最初の値 - イテレータに知られていないさらにアウト

イテレータは、通常、巻き戻し()はforeachの()によって実行された第1 ...

他のヒント

全体Iteratorインターフェイスを実装する余裕がおよび/または私もこのに実行してきたイテレータのデコレータを作成するためにIteratorIteratorクラスを拡張しながらます。

デコレータがすでに問題を解決すること、それが唯一の矛盾を取り除くために欠けている機能を実装する必要があります。自動巻き戻しの必要はありません。

class IteratorDecorator extends IteratorIterator
{
    public function valid()
    {
        return $this->getInnerIterator()->valid();
    }
}

例:あなたは、例えば、デフォルトで有効ですIteratorオブジェクトを使用している場合ArrayIteratorます:

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

$itit = new IteratorIterator($it);
var_dump($itit->valid());           # bool(false)

このはIteratorIteratorオブジェクトが正しくインナーIteratorIteratorの状態を反映していない、うまくArrayIterator実装の矛盾を示しています。 IteratorDecoratorを使用すると、これを癒すことができます:

$decor = new IteratorDecorator($it);
var_dump($decor->valid());          # bool(true)

そして、あなたがここまで続いている場合は、ここにあなたが考慮する必要があります別の特殊なケースである:あなたが内部イテレータとrewindする必要はありません場合は、あなただけのようにも正しい妥当性を返すNoRewindIteratorを使用することができます:

$noretit = new NoRewindIterator($it);
var_dump($noretit->valid());        # bool(true)
NoRewindIteratorはイテレータが巻き戻されるべきではないことを期待して正しく内部イテレータの有効性を示したように、

のアカウントにヨハネス「自動巻き戻しなし」の引数を考えると、これは、理にかなっています。

しかしIteratorDecoratorが示すように、私は矛盾を削除するだけでなく、自動巻き戻しのいずれかの種類を行いません。

@johannesは言っ

のように、位置がIteratorIteratorに初期化されていませんし、それの方法のいずれかの他は、それ上で実行されているか、foreachのに使用される前に、それが有効ではありませんのでれる()

タグを行うようにしてください
var_dump( $iterIter->current() ); // NULL
var_dump( $iterIter->getInnerIterator()->current() ); // 1

$iterIter->rewind();
var_dump( $iterIter->current() ); // 1
var_dump( $iterIter->getInnerIterator()->->current() );  // 1

そしてまたunitiliazed IteratorIterator上の点に注意します:

$iterIter->next(); // 2
var_dump( $iterIter->current()) ; // 2 (from NULL to 2)
var_dump( $iterIter->getInnerIterator()->current() );  // 2

あなたのコードスニペットからその$arrayIter$iterIter->getInnerIterator()と同じであることに注意してください。

いくつかの光を当てる希望ます。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top