Skip to content

Modul 10 — Closures & Iteratoren

Funktionen als Werte: Closures mit Captures, der Iterator-Trait, Adapter-Ketten ohne Zwischen-Kopien — und eine Log-Auswertung als Mini-Projekt.

Fortschritt0/4 Lektionen
37

Closures: Funktionen mit Gedächtnis

Lektion 37 von 4

Manchmal brauchst du eine kleine Funktion genau an einer Stelle — ein Vergleichskriterium, ein Bonus-Rechner, ein Callback. Dafür sind Closures da: Funktionen, die ihre Umgebung mit einfangen.

fn main() {
    let basis = 7;

    let verdopple_mit = |x: i32| x * basis;

    println!("{}", verdopple_mit(6));
}

Die Closure fängt basis aus der Umgebung ein — ohne dass du es deklarieren musst. Der Compiler leitet Typen her und entscheidet, WIE gefangen wird: per Referenz zum Lesen, per Referenz zum Ändern oder — mit move — per Besitz. Closures, die ihre Umgebung verändern, implementieren FnMut und brauchen eine mut-Bindung:

fn main() {
    let mut punkte = 0;

    let mut punkte_dazu = |bonus: i32| punkte += bonus;

    punkte_dazu(5);
    punkte_dazu(3);
    println!("Punkte: {punkte}");
}

Die drei Closure-Traits

  • FnOnce — ruft sich selbst auf und verbraucht dabei Captures (z. B. bei move)
  • Fn — liest Captures, beliebig oft aufrufbar
  • FnMut — ändert Captures, braucht eine mut-Bindung
  • move erzwingt Besitz statt Leihen — Pflicht bei Threads (Modul 12!)
let name = String::from("Rust");
name

name besitzt den String.

Schritt 1 von 3

Probiere es aus: baue eine Closure, die eine Eingabe mit deinem persönlichen Faktor multipliziert.

Closure-WerkstattBereit
Editor wird geladen…

Übung: Closures fangen

🧩 Übung m10-l1-e1

🔮 Vorhersage: Was passiert beim Ausführen?

Editor wird geladen…
KI-Tutor (sokratisch — keine Komplettlösungen)

✅ Wichtige Erkenntnisse

0/3

Haken setzen, um deinen Lernfortschritt zu markieren:

38

Der Iterator-Trait: next() ist alles

Lektion 38 von 4

Hinter jedem for-loop steckt ein Iterator — ein Objekt mit einer einzigen Methode:

struct Zaehler {
    bis: u32,
    aktuell: u32,
}

impl Iterator for Zaehler {
    type Item = u32;

    fn next(&mut self) -> Option<u32> {
        if self.aktuell < self.bis {
            self.aktuell += 1;
            Some(self.aktuell)
        } else {
            None
        }
    }
}

fn main() {
    for n in Zaehler { bis: 4, aktuell: 0 } {
        println!("{n}");
    }
}

next() liefert Some(Item) pro Element und None am Ende — mehr ist der ganze Vertrag nicht. Implementierst du Iterator für deinen Typ, bekommst du alle Adapter-Methoden der Standardbibliothek gratis: map, filter, sum, collect, take, zip ... Die ~70 Methoden haben alle dieselbe Basis.

Und wichtig: Iteratoren sind lazy. (1..=1_000_000) rechnet noch nichts — erst ein Verbraucher treibt die Kette an.

Übung: Iterator selbst bauen

🧩 Übung m10-l2-e1

🔮 Vorhersage: Was passiert beim Ausführen?

Editor wird geladen…
KI-Tutor (sokratisch — keine Komplettlösungen)

✅ Wichtige Erkenntnisse

0/3

Haken setzen, um deinen Lernfortschritt zu markieren:

39

Adapter-Ketten: filter, map, collect

Lektion 39 von 4

Jetzt der Lohn: Adapter verketten sich zu Pipelines — und keine Stufe kopiert etwas.

fn main() {
    let zahlen = vec![1, 2, 3, 4];

    let zehner: Vec<u32> = zahlen
        .iter()
        .filter(|z| *z % 2 == 0)
        .map(|z| z * 10)
        .collect();

    println!("{zehner:?}");
}

Drei Rollen in der Kette:

  • Adapter (lazy) — filter, map, take, cloned: bauen nur die Pipeline-Beschreibung auf
  • Verbraucher (tatkräftig) — collect, sum, count, max, any: treiben next() an, bis None kommt
  • collect — sammelt in fast jeden Zieltyp: Vec, String, sogar ein Result über die ganze Kette

Letzteres ist der Geheimtipp: collect::<Result<Vec<u32>, String>>() liefert entweder alle Werte — oder den ersten Fehler. Eine Pipeline von Results wird zum Result einer Pipeline.

Und weil alles Slices leihen statt kopieren: die Kette oben verbraucht zahlen nicht — sie leiht. Ein into_iter() wäre die besitzende Variante.

Übung: Pipeline bauen

🧩 Übung m10-l3-e1

🔮 Vorhersage: Was passiert beim Ausführen?

Editor wird geladen…
KI-Tutor (sokratisch — keine Komplettlösungen)

✅ Wichtige Erkenntnisse

0/3

Haken setzen, um deinen Lernfortschritt zu markieren:

40

Mini-Projekt: Log-Auswertung

Lektion 40 von 4

Erst das Szenario aus dem Arbeitsalltag — dann die Übung:

Praxis-Szenario: Die Log-Datei in der Konsole

Nach jedem Deployment sichtet dein Team per Hand die Logdatei: Welche Fehler gab es? Welche Zeile ist die längste, weil dort vermutlich ein Timeout gedruckt wurde? Kollegen kopieren Zeilen in Excel, andere schreiben Shell-Pipelines mit grep und awk — niemand kann die beiden Antworten in einem Rutsch aus dem Programm ziehen.

🧩 Übung m10-l4-e1

🔮 Vorhersage: Was passiert beim Ausführen?

Editor wird geladen…
KI-Tutor (sokratisch — keine Komplettlösungen)

Was du in Modul 10 geschafft hast

  • Closures fangen Umgebung ein — Fn/FnMut/FnOnce bestimmen die Aufruf-Regeln
  • Eigene Iteratoren: next() implementieren, alle Adapter erben
  • Pipelines ohne Kopien — lazy bis zum Verbraucher
  • Eine Auswertung, die zwei Fragen in einer Zeile je beantwortet

✅ Wichtige Erkenntnisse

0/3

Haken setzen, um deinen Lernfortschritt zu markieren:

Modul-Checkpoint

Checkpoint: Modul 10

Bestehensgrenze: 80 %. Der Versuch wird bewertet und zählt für das Modul-Gate.

This site uses essential cookies for Stripe payments. No tracking cookies.