Implementierung von Iteratoren in Rust

RustRustBeginner
Jetzt üben

This tutorial is from open-source community. Access the source code

💡 Dieser Artikel wurde von AI-Assistenten übersetzt. Um die englische Version anzuzeigen, können Sie hier klicken

Einführung

In diesem Lab lernen wir das Iterator-Trait in Rust kennen, das verwendet wird, um Iteratoren über Sammlungen wie Arrays zu implementieren. Das Iterator-Trait erfordert, dass die next-Methode für den Iterator definiert wird und kann in einem impl-Block manuell implementiert oder automatisch für Arrays und Bereiche definiert werden. Die for-Konstruktion kann verwendet werden, um einige Sammlungen mit der .into_iter()-Methode bequem in Iteratoren umzuwandeln. Das Lab bietet eine Beispielimplementierung des Fibonacci-Sequenzgenerators als Iterator, die zeigt, wie man die next-Methode definiert und das Iterator-Trait verwendet. Darüber hinaus wird die Verwendung der take- und skip-Methoden zum Manipulieren von Iteratoren sowie die iter-Methode zum Iterieren über Arrays demonstriert.

Hinweis: Wenn das Lab keinen Dateinamen angibt, können Sie einen beliebigen Dateinamen verwenden. Beispielsweise können Sie main.rs verwenden und es mit rustc main.rs &&./main kompilieren und ausführen.

Iteratoren

Das Iterator-Trait wird verwendet, um Iteratoren über Sammlungen wie Arrays zu implementieren.

Das Trait erfordert nur, dass eine Methode für das next-Element definiert wird, die entweder manuell in einem impl-Block definiert oder automatisch definiert werden kann (wie bei Arrays und Bereichen).

Als praktische Abkürzung für häufige Situationen verwandelt die for-Konstruktion einige Sammlungen in Iteratoren mit der .into_iter()-Methode.

struct Fibonacci {
    curr: u32,
    next: u32,
}

// Implementiere `Iterator` für `Fibonacci`.
// Das `Iterator`-Trait erfordert nur, dass eine Methode für das `next`-Element definiert wird.
impl Iterator for Fibonacci {
    // Wir können diesen Typ mit Self::Item referenzieren.
    type Item = u32;

    // Hier definieren wir die Sequenz mit `.curr` und `.next`.
    // Der Rückgabetyp ist `Option<T>`:
    //     * Wenn der `Iterator` beendet ist, wird `None` zurückgegeben.
    //     * Andernfalls wird der nächste Wert in `Some` verpackt und zurückgegeben.
    // Wir verwenden Self::Item im Rückgabetyp, so dass wir den Typ ändern können,
    // ohne die Funktionssignaturen aktualisieren zu müssen.
    fn next(&mut self) -> Option<Self::Item> {
        let current = self.curr;

        self.curr = self.next;
        self.next = current + self.next;

        // Da es kein Endpunkt für eine Fibonacci-Sequenz gibt, wird der `Iterator`
        // niemals `None` zurückgeben, und `Some` wird immer zurückgegeben.
        Some(current)
    }
}

// Gibt einen Fibonacci-Sequenzgenerator zurück.
fn fibonacci() -> Fibonacci {
    Fibonacci { curr: 0, next: 1 }
}

fn main() {
    // `0..3` ist ein `Iterator`, der 0, 1 und 2 generiert.
    let mut sequence = 0..3;

    println!("Vier aufeinanderfolgende `next`-Aufrufe auf 0..3");
    println!("> {:?}", sequence.next());
    println!("> {:?}", sequence.next());
    println!("> {:?}", sequence.next());
    println!("> {:?}", sequence.next());

    // `for` iteriert über einen `Iterator`, bis er `None` zurückgibt.
    // Jeder `Some`-Wert wird entpackt und an eine Variable gebunden (hier `i`).
    println!("Iteriere über 0..3 mit `for`");
    for i in 0..3 {
        println!("> {}", i);
    }

    // Die `take(n)`-Methode reduziert einen `Iterator` auf seine ersten `n` Elemente.
    println!("Die ersten vier Elemente der Fibonacci-Sequenz sind: ");
    for i in fibonacci().take(4) {
        println!("> {}", i);
    }

    // Die `skip(n)`-Methode kürzt einen `Iterator` ab, indem sie seine ersten `n` Elemente weglässt.
    println!("Die nächsten vier Elemente der Fibonacci-Sequenz sind: ");
    for i in fibonacci().skip(4).take(4) {
        println!("> {}", i);
    }

    let array = [1u32, 3, 3, 7];

    // Die `iter`-Methode erzeugt einen `Iterator` über ein Array/Slice.
    println!("Iteriere das folgende Array {:?}", &array);
    for i in array.iter() {
        println!("> {}", i);
    }
}

Zusammenfassung

Herzlichen Glückwunsch! Sie haben das Iterators-Lab abgeschlossen. Sie können in LabEx weitere Labs absolvieren, um Ihre Fähigkeiten zu verbessern.