Menu
Coddy logo textTech

Iterable & Iterator

Teil des Abschnitts Objektorientierte Programmierung der Dart-Journey von Coddy. Lektion 68 von 110.

Jedes Mal, wenn du eine for-in-Schleife für eine List, ein Set oder eine andere Sammlung verwendest, arbeitest du im Hintergrund mit Iterable und Iterator. Wenn du diese Konzepte verstehst, kannst du deine eigenen Klassen erstellen, über die iteriert werden kann.

Ein Iterable ist jedes Objekt, das eine Folge von Werten erzeugen kann. Es hat eine zentrale Anforderung: einen iterator-Getter, der einen Iterator zurückgibt. Der Iterator bewegt sich tatsächlich Schritt für Schritt durch die Elemente:

var numbers = [1, 2, 3];
var iterator = numbers.iterator;

while (iterator.moveNext()) {
  print(iterator.current);  // 1, dann 2, dann 3
}

Die Methode moveNext() rückt zum nächsten Element vor und gibt true zurück, wenn eines vorhanden ist, oder false, wenn der Vorgang abgeschlossen ist. Die Eigenschaft current liefert das aktuelle Element.

Um Ihre eigene Klasse iterierbar zu machen, implementieren Sie das Iterable-Interface:

class Countdown extends Iterable<int> {
  final int start;
  Countdown(this.start);
  
  @override
  Iterator<int> get iterator => CountdownIterator(start);
}

class CountdownIterator implements Iterator<int> {
  int _current;
  
  CountdownIterator(int start) : _current = start + 1;
  
  @override
  int get current => _current;
  
  @override
  bool moveNext() {
    if (_current > 0) {
      _current--;
      return true;
    }
    return false;
  }
}

void main() {
  for (var n in Countdown(3)) {
    print(n);  // 3, 2, 1, 0
  }
}

Jetzt funktioniert Countdown mit for-in-Schleifen und allen Iterable-Methoden wie map, where und fold. Dieses Muster ist unerlässlich, wenn du benutzerdefinierte Sammlungen erstellst, die sich nahtlos in das Collection-Ökosystem von Dart integrieren.

challenge icon

Aufgabe

Einfach

Erstellen wir einen benutzerdefinierten Bereichsgenerator, der mit einer for-in-Schleife durchlaufen werden kann! Du erstellst deine eigenen Klassen Iterable und Iterator, um eine Zahlenfolge innerhalb eines angegebenen Bereichs zu erzeugen.

Du organisierst deinen Code in zwei Dateien:

  • range.dart: Erstelle zwei Klassen, die zusammenarbeiten, um eine Zahlenfolge zu erzeugen:
    • Eine Klasse RangeIterator, die Iterator<int> implementiert. Sie soll die aktuelle Position verfolgen und wissen, wann sie stoppen muss. Der Iterator startet vor dem ersten Element, daher muss moveNext() aufgerufen werden, bevor auf current zugegriffen wird.
    • Eine Klasse Range, die Iterable<int> erweitert. Sie übernimmt in ihrem Konstruktor einen start- und einen end-Wert und stellt einen iterator-Getter bereit, der einen RangeIterator zurückgibt.
    Der Bereich soll sowohl start als auch end einschließen. Zum Beispiel soll Range(1, 5) Folgendes erzeugen: 1, 2, 3, 4, 5.
  • main.dart: Importiere deine Bereichsdatei und demonstriere dein benutzerdefiniertes Iterable:
    • Erstelle ein Range(1, 5) und verwende eine for-in-Schleife, um jede Zahl in einer eigenen Zeile auszugeben
    • Gib eine leere Zeile aus
    • Erstelle ein Range(10, 13) und verwende die Methode map, um jeden Wert zu verdoppeln, und gib anschließend die resultierende Liste aus

Da deine Klasse Range Iterable erweitert, erhält sie automatisch Zugriff auf alle leistungsstarken Sammlungsmethoden wie map, where und fold – das ist das Schöne daran, die Iterable-Schnittstelle zu implementieren!

Erwartete Ausgabe:

1
2
3
4
5

[20, 22, 24, 26]

Probier es selbst

import 'range.dart';

void main() {
  // TODO: Erstelle eine Range(1, 5) und verwende eine for-in-Schleife, um jede Zahl auszugeben
  
  
  // TODO: Gib eine Leerzeile aus
  
  
  // TODO: Erstelle eine Range(10, 13), verwende map, um jeden Wert zu verdoppeln, und gib die Liste aus
  
}
quiz iconTeste dich selbst

Diese Lektion enthält ein kurzes Quiz. Starte die Lektion, um es zu beantworten und deinen Fortschritt zu speichern.

Alle Lektionen in Objektorientierte Programmierung

Übe selbstständig: Online-Dart-Compiler