Question

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

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

Si je premier appel $ iterIter-> rewind () , puis $ iterIter-> valide () est vrai. Je suis curieux de savoir pourquoi il faut que rewind () soit appelé. J'imagine qu'il ya de bonnes raisons pour cela, mais je me serais attendu à commencer simplement itération quel que soit l'état, il est iterator intérieur est, et le laisser en option pour revenir en arrière avant de commencer l'itération.

appelant à côté () semble aussi mettre dans un état « valide » (bien qu'il avance à la position suivante, ce qui suggère qu'il était auparavant à la première position).

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

$iterIter->next();
var_dump($iterIter->valid()); 

Encore une fois, je suis curieux de savoir pourquoi je dois appeler rewind (), en dépit de l'itérateur interne étant dans un état valide.

Était-ce utile?

La solution

Avec une nouvelle iterator position n'est pas initialisé, simplement pour des raisons de performances, vous pouvez empiler itérateurs sur d'autres itérateurs, si tous seraient un retour rapide pendant la construction il y aurait un certain impact sur les performances, en plus des itérateurs pourraient changer première valeur après que le constructeur a été exécuté -. qui est inconnu itérateurs plus loin

itérateurs sont généralement exécutés par foreach () qui fait un retour rapide () d'abord ...

Autres conseils

Alors que l'extension de la classe IteratorIterator pour épargner la mise en œuvre toute interface iterator et / ou de créer un décorateur d'un itérateur Je cours dans ce aussi bien.

Ce décorateur est déjà la solution au problème, il n'a besoin que de mettre en œuvre les fonctionnalités manquantes pour supprimer l'incohérence. Pas besoin d'un rembobinage automatique:

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

Exemple: Si vous avez un objet Iterator valide par défaut, par exemple ArrayIterator:

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

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

Cela montre l'incohérence de la mise en œuvre de IteratorIterator bien, l'objet IteratorIterator ne reflète pas l'état du ArrayIterator intérieur. En utilisant le IteratorDecorator peut guérir ceci:

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

Et si vous avez suivi jusqu'à ici, voici un autre cas particulier, vous voudrez peut-être envisager: Si vous n'avez pas besoin d'avoir rewind avec l'itérateur interne, vous pouvez simplement utiliser la NoRewindIterator qui retourne la validité correcte ainsi :

$noretit = new NoRewindIterator($it);
var_dump($noretit->valid());        # bool(true)

Taken Johannes « pas auto-rewind » arguments en compte, cela fait sens, comme le NoRewindIterator attend à ce que l'itérateur ne doit pas être rembobinées et montre correctement la validité de l'itérateur interne.

Mais comme le montre IteratorDecorator, je ne fais aucune sorte de rembobinage automatique et de supprimer l'incohérence.

Comme @johannes a dit, la position n'a pas été initialisé dans le IteratorIterator et il est donc pas valable avant tout autre de celui-ci pour des méthodes sont exécutées sur le ou il est utilisé avec foreach ()

Essayez de faire

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

Et

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

Et notez aussi que sur une IteratorIterator unitiliazed:

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

Notez que $arrayIter de votre extrait de code est identique à $iterIter->getInnerIterator().

L'espoir que faire la lumière.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top