Iteratore

Questo articolo può contenere lavori non pubblicati o dichiarazioni non verificate (ottobre 2014).

Puoi aiutare aggiungendo riferimenti o rimuovendo contenuti non pubblicati. Vedi la pagina di discussione per maggiori dettagli.

In ingegneria del software , l' iteratore è un modello di progettazione (design pattern) comportamento .

Un iteratore è un oggetto che ti permette di sfogliare tutti gli elementi contenuti in un altro oggetto, molto spesso un contenitore ( lista , albero , ecc.). Un sinonimo di iteratore è cursore , soprattutto nel contesto dei database .

Descrizione

Un iteratore si presenta come un puntatore con essenzialmente due primitive: accedere all'elemento puntato corrente (nel contenitore) e spostarsi per puntare all'elemento successivo. Inoltre, è necessario poter creare un iteratore che punta al primo elemento; oltre a determinare in qualsiasi momento se l'iteratore ha esaurito tutti gli elementi nel contenitore. Diverse implementazioni possono anche offrire comportamenti aggiuntivi.

L'obiettivo di un iteratore è quello di consentire al suo utente di navigare nel contenitore, vale a dire accedere in sequenza a tutti i suoi elementi per applicare l'elaborazione ad essi, isolando l'utente dalla struttura interna del contenitore, potenzialmente complesso. In questo modo il contenitore può archiviare gli elementi come preferisce, consentendo comunque all'utente di trattarli come un semplice elenco. Molto spesso l'iteratore è progettato contemporaneamente alla classe contenitore che dovrà sfogliare, e sarà il contenitore stesso che creerà e distribuirà gli iteratori per accedere ai suoi elementi.

Differenze con l'indicizzazione

Nei linguaggi procedurali, un indice viene spesso utilizzato in un semplice ciclo , per accedere in sequenza a tutti gli elementi, in particolare a un array. Sebbene questo approccio sia ancora possibile nella programmazione a oggetti per alcuni contenitori, l'uso di iteratori presenta alcuni vantaggi:

La possibilità che un contenitore venga modificato durante un'iterazione è diventata necessaria nella moderna programmazione a oggetti , dove le relazioni tra gli oggetti e l'effetto di determinate operazioni possono diventare un mal di testa. Utilizzando un iteratore così "robusto", siamo risparmiati da questi inconvenienti.

Utilizzando un iteratore esplicito

In un linguaggio orientato agli oggetti come C #, un iteratore è un oggetto che implementa l'interfaccia IEnumerator.

interface IEnumerator { void Reset(); bool MoveNext(); object Current { get; } }

L'iteratore viene utilizzato per accedere ai valori disponibili.

IterateurTypique iterateur = new IterateurTypique(); iterateur.Reset(); // optionnel : cet appel peut ne pas être effectué. while(iterateur.MoveNext()){ Console.WriteLine(iterateur.Current); }

Una delle tante possibili implementazioni di oggetti potrebbe essere simile a questa.

class IterateurTypique : IEnumerator { private string[] _chainesAParcourir = new string[] { "TF1", "France2", "FR3", "Canal+" }; private int _positionCourante = -1; public void Reset() { _positionCourante = -1; } public bool MoveNext() { if( _positionCourante + 1 >= _chainesAParcourir.Length ) return false; _positionCourante +=1; return true; } public object Current { get { return _chainesAParcourir[_positionCourante]; } } }

L'interfaccia IEnumerableC # consente il passaggio a un iteratore implicito.

interface IEnumerable { IEnumerator GetEnumerator(); }

Matrici, elenchi o dizionari C # sono tipi derivati ​​da IEnumerablee hanno un metodo GetEnumerator()che chiama l'iteratore esplicito.

L'istruzione foreach di C # chiama questo metodo GetEnumerator()e itera esplicitamente nascondendo i dettagli dell'implementazione.

if(Television is IEnumerable) { foreach(object chaine in Television) { Console.WriteLine(chaine); } }

Iteratori impliciti

Linguaggi orientati agli oggetti come Perl e Python forniscono un modo "interno" per iterare sugli elementi di un contenitore senza introdurre esplicitamente un iteratore. Questo è spesso implementato da una struttura di controllo per ogni , come nei seguenti esempi:

# Tcl: itérateur implicite foreach val $list { puts stdout $val } # Perl: itérateur implicite foreach $val (@list) { print "$val\n"; } # Python, itérateur implicite for Value in List: print Value // PHP, itérateur implicite foreach ($list as $value) print $value; // Java, J2SE 5.0, itérateur implicite for (Value v : list) System.out.print(v); // C#, itérateur implicite foreach (object obj in list) Console.WriteLine(obj ); // C#, itérateur explicite avec un yield foreach (object obj in IndicesPairs() ) Console.WriteLine(obj); // ou IndicesPairs() est une méthode IEnumerable IndicesPairs() { for(int i=0; i<tableau.Length; i++) if(i%2==0) yield return tableau[i]; } # Ruby, itérateur de bloc, (yield) list.each do |value| puts value end # ou each est une méthode de Array tel que : def each for i in 0...size yield(self[i]) end end

Attenzione, in Javascript non iteriamo direttamente sugli oggetti ma sul loro nome

// Javascript, itérateur implicite for(nom in Object) { var valeur = Object[nom]; alert(Value+" = "+valeur ]); }

Il linguaggio C ++ ha anche la funzione template std::for_each()che consente iterazioni implicite simili, ma richiede comunque di fornire oggetti iteratori come parametri di input.

Nota  : Ruby, Python e C # dalla sua versione 2.0, offrono tramite yielduno strumento specifico per costruire iteratori.

Il linguaggio PHP implementa gli iteratori dalla sua versione 5 tramite SPL .