0Pricing
Learn Rust Coding · Lektion

Fn, FnMut, FnOnce

Closure-Traits

Fn, FnMut, FnOnce ist eine kostenlose Learn Rust Coding-Lektion auf CoddyKit. Dies ist Lektion 4 von 4. Du kannst die komplette Lektion unten kostenlos lesen – dann übst du sie direkt im Browser mit einem integrierten Code-Editor und einem KI-Tutor rund um die Uhr. Sie ist Teil des Learn Rust Coding-Lernpfads, und dein Fortschritt wird über Web und CoddyKit-App synchronisiert. Der Learn Rust Coding-Kurs umfasst insgesamt 4 Lektionen.

Die Closure-Traits

Jede Closure implementiert automatisch abhängig davon, wie sie erfasste Werte verwendet, eines oder mehrere von drei Traits:

  • Fn — leiht unveränderlich aus.
  • FnMut — leiht veränderlich aus.
  • FnOnce — übernimmt den Besitz und kann einmal aufgerufen werden.
fn main() {
    let x = 5;
    let show = || println!("x is {}", x); // implements Fn
    show();
    show();
}

Fn: Unveränderliches Ausleihen

Eine Closure, die erfasste Werte nur liest, implementiert Fn. Sie kann beliebig oft aufgerufen werden, ohne etwas zu verändern.

fn main() {
    let greeting = String::from("Hi");
    let say = || println!("{}", greeting);
    say();
    say();
}

FnMut: Veränderliches Ausleihen

Eine Closure, die einen erfassten Wert ändert, implementiert FnMut. Die Closure-Variable selbst muss mut sein, damit die Closure aufgerufen werden kann.

fn main() {
    let mut count = 0;
    let mut increment = || {
        count += 1;
        println!("count {}", count);
    };
    increment();
    increment();
}

FnOnce: Besitz übernehmen

Eine Closure, die einen erfassten Wert aus der Umgebung verschiebt, implementiert FnOnce. Sie kann nur ein einziges Mal aufgerufen werden.

fn main() {
    let name = String::from("Ada");
    let consume = move || {
        let owned = name;
        println!("consumed {}", owned);
    };
    consume();
}

Die Trait-Hierarchie

Die Traits bilden eine Hierarchie:

  • Jedes Fn ist auch FnMut und FnOnce.
  • Jedes FnMut ist auch FnOnce.

Damit ist Fn am flexibelsten und FnOnce am wenigsten flexibel.

fn main() {
    let value = 42;
    let read = || value; // Fn, so also FnMut and FnOnce
    println!("{}", read());
}

Fn an Funktionen übergeben

Eine Funktion kann eine Closure akzeptieren, indem Sie angeben, welches Trait sie benötigt. Verwenden Sie Generics mit einer Trait-Einschränkung.

fn apply<F: Fn(i32) -> i32>(f: F, x: i32) -> i32 {
    f(x)
}

fn main() {
    let double = |n| n * 2;
    println!("{}", apply(double, 9));
}

FnMut akzeptieren

Wenn Ihre Funktion den erfassten Zustand verändern muss, verlangen Sie FnMut und markieren Sie den Parameter mit mut.

fn call_twice<F: FnMut()>(mut f: F) {
    f();
    f();
}

fn main() {
    let mut total = 0;
    call_twice(|| total += 1);
    // note: total is borrowed during the call
}

FnOnce akzeptieren

Wenn eine Funktion die Closure nur einmal aufruft und ihr erlaubt, Werte zu verbrauchen, verlangen Sie FnOnce.

fn run_once<F: FnOnce() -> String>(f: F) {
    let result = f();
    println!("{}", result);
}

fn main() {
    let s = String::from("done");
    run_once(move || s);
}

Das Schlüsselwort move

Das Schlüsselwort move zwingt eine Closure dazu, den Besitz der erfassten Variablen zu übernehmen, anstatt sie auszuleihen.

Das ist unverzichtbar, wenn eine Closure den Gültigkeitsbereich überleben muss, in dem sie erstellt wurde, etwa in Threads.

fn main() {
    let data = vec![1, 2, 3];
    let printer = move || println!("{:?}", data);
    printer();
}

Wie Rust das Trait auswählt

Sie wählen das Trait nicht manuell aus. Der Compiler entscheidet anhand des Rumpfs der Closure:

  • Nur lesen → Fn
  • Verändern → FnMut
  • Einen erfassten Wert herausverschieben → FnOnce
fn main() {
    let mut log = Vec::new();
    let mut record = |x: i32| log.push(x); // FnMut
    record(1);
    record(2);
    println!("{:?}", log);
}

Die richtige Einschränkung wählen

Als Faustregel gilt:

  • Akzeptieren Sie Fn, wenn Sie die Closure nur aufrufen und lesen müssen.
  • Akzeptieren Sie FnMut, wenn die Closure den Zustand verändert.
  • Akzeptieren Sie FnOnce, wenn ein einmaliger Aufruf ausreicht.

Wählen Sie die großzügigste passende Einschränkung.

fn each<F: Fn(i32)>(items: &[i32], f: F) {
    for &i in items {
        f(i);
    }
}

fn main() {
    each(&[1, 2, 3], |n| println!("got {}", n));
}

Kurze Überprüfung

Ordnen Sie das Verhalten einer Closure ihrem Trait zu.

Zusammenfassung

Die drei Closure-Traits:

  • Fn — leiht unveränderlich aus und kann wiederholt aufgerufen werden.
  • FnMut — leiht veränderlich aus und kann den Zustand ändern.
  • FnOnce — übernimmt den Besitz und kann einmal aufgerufen werden.

Der Compiler leitet das Trait ab; move erzwingt das Erfassen durch Besitzübernahme.

fn main() {
    let base = 5;
    let adder = move |x: i32| x + base; // Fn, captures base by move
    println!("{}", adder(10));
}

Häufig gestellte Fragen

Ist die Lektion „Fn, FnMut, FnOnce“ kostenlos?

Ja — der vollständige Text von „Fn, FnMut, FnOnce“ ist hier im Web kostenlos zu lesen. Um sie interaktiv zu üben (integrierter Code-Editor und 24/7 KI-Tutor) und den Rest des Learn Rust Coding-Kurses freizuschalten, upgrade auf CoddyKit PRO. Der Learn Rust Coding-Kurs umfasst insgesamt 4 Lektionen.

Was lerne ich in „Fn, FnMut, FnOnce“?

Closure-Traits Du übst Learn Rust Coding mit praktischem Code, den du direkt im Browser ausführst, und ein 24/7 KI-Tutor beantwortet deine Fragen während du die Lektion bearbeitest.

Brauche ich Erfahrung, um Learn Rust Coding zu starten?

Keine Vorkenntnisse erforderlich. Learn Rust Coding auf CoddyKit ist für Anfänger bis fortgeschrittene Lernende strukturiert, sodass du hier starten oder von Anfang an beginnen und in deinem eigenen Tempo voranschreiten kannst. Dies ist Lektion 4 von 4.

Wie lange dauert die Lektion „Fn, FnMut, FnOnce“?

Die meisten CoddyKit-Lektionen dauern etwa 5–10 Minuten. Jede ist kompakt und interaktiv, sodass du stetig Fortschritte machst und genau dort weitermachst, wo du aufgehört hast – im Web und in der App.

Kann ich in dieser Learn Rust Coding-Lektion Code schreiben und ausführen?

Ja. Jede Learn Rust Coding-Lektion enthält einen integrierten Code-Editor, sodass du echten Code direkt in deinem Browser schreibst und ausführst und sofort KI-Feedback erhältst — ohne lokale Einrichtung erforderlich.

Alle Lektionen in diesem Kurs

  1. Funktionen definieren
  2. Ausdrücke und Anweisungen
  3. Closures
  4. Fn, FnMut, FnOnce
← Zurück zu Learn Rust Coding