RecursiveIteratorIterator gibt zusätzliche Elemente zurück

8

RecursiveIteratorIterator liefert zusätzliches Ergebnis, wenn rewind() nicht vor while loop

aufgerufen wird

Beispiel

%Vor%

Ausgabe

%Vor%
  • Warum ein extra A nicht C ?
  • Das Array wurde nie initiiert oder aufgerufen. Warum ist $iterator->rewind() für die while-Schleife
  • erforderlich?
  • foreach funktioniert perfekt, ohne dass rewind aufgerufen werden muss. what die Unterschiede zwischen foreach und while beim Arbeiten mit Iteratoren

Code in Aktion

    
Baba 25.11.2012, 21:51
quelle

1 Antwort

5

Ich beantworte die Fragen in umgekehrter Reihenfolge:

  

foreach funktioniert perfekt, ohne rewind aufrufen zu müssen, was die Unterschiede zwischen diesen foreach und while beim Arbeiten mit Iteratoren sind

foreach ruft intern rewind() auf, deshalb müssen Sie es nicht selbst tun. Dies ist immer der Fall. Selbst wenn Sie bereits einen Iterator verwendet haben, beginnt die foreach -Schleife von vorne. (Sie können dies vermeiden, indem Sie es in NoRewindIterator einfügen).

  

Das Array wurde nie initiiert oder aufgerufen Warum ist $ iterator- & gt; rewind () für die while-Schleife erforderlich

Die SPL-Iteratoren sind für die Verwendung mit foreach vorgesehen und verhindern in diesem Fall doppelte Methodenaufrufe. Wenn die RecursiveIteratorIterator die Methode RecursiveArrayIterator::rewind() für die Konstruktion aufrufen würde, würde sie erneut aufgerufen werden, wenn die foreach -Schleife beginnt. Deshalb ist der Anruf nicht erledigt.

  

Warum ein extra A nicht C?

Um das herauszufinden, ist es schön zu sehen, welche Methoden von RecursiveArrayIterator tatsächlich aufgerufen werden:

%Vor%

Dies erzeugt die folgende Ausgabe:

%Vor%

Die Ausgabe sieht ein bisschen seltsam aus, insbesondere die zweite Iteration verfehlt den next() Aufruf, also bleibt sie einfach am selben Element.

Der Grund dafür ist eine Besonderheit in der RecursiveIteratorIterator -Implementierung: Iteratoren beginnen im RS_START -Zustand und der erste next -Aufruf in diesem Zustand überprüft nur hasChildren() , ruft aber nicht den zugrunde liegenden Iterator auf next() Methode. Danach wird in den Modus RS_NEXT gewechselt, in dem der Aufruf next() ordnungsgemäß ausgeführt wird. Deshalb wird die Vorwärtsbewegung um einen Schritt verzögert.

In meinen Augen ist das ein Fehler, aber Ссылка behauptet etwas anderes.

    
NikiC 25.11.2012, 22:00
quelle

Tags und Links