0Pricing
Learn Rust Coding · Lekcja

Fn, FnMut, FnOnce

Cechy domknięć

Fn, FnMut, FnOnce to bezpłatna lekcja Learn Rust Coding na CoddyKit. To lekcja 4 z 4. Możesz przeczytać całą lekcję poniżej za darmo — a potem ćwiczyć ją interaktywnie w przeglądarce z wbudowanym edytorem kodu i tutorem AI dostępnym 24/7. To część ścieżki edukacyjnej Learn Rust Coding, a Twój postęp synchronizuje się między webem a aplikacją CoddyKit. Kurs Learn Rust Coding zawiera 4 lekcji w sumie.

Cechy domknięć

Każde domknięcie automatycznie implementuje jedną lub więcej z trzech cech, zależnie od sposobu używania przechwyconych wartości:

  • Fn — pożycza niezmiennie.
  • FnMut — pożycza mutowalnie.
  • FnOnce — przejmuje własność i można je wywołać raz.
fn main() {
    let x = 5;
    let show = || println!("x is {}", x); // implements Fn
    show();
    show();
}

Fn: pożyczanie niezmienne

Domknięcie, które tylko odczytuje przechwycone wartości, implementuje Fn. Można je wywoływać wiele razy bez wprowadzania zmian.

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

FnMut: pożyczanie mutowalne

Domknięcie, które zmienia przechwyconą wartość, implementuje FnMut. Sama zmienna domknięcia musi być oznaczona jako mut, aby można było je wywołać.

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

FnOnce: przejmowanie własności

Domknięcie, które przenosi przechwyconą wartość ze środowiska, implementuje FnOnce. Można je wywołać tylko raz.

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

Hierarchia cech

Cechy tworzą hierarchię:

  • Każde Fn jest również FnMut i FnOnce.
  • Każde FnMut jest również FnOnce.

Dlatego Fn jest najbardziej elastyczne, a FnOnce — najmniej.

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

Przekazywanie Fn do funkcji

Funkcja może przyjmować domknięcie, określając wymaganą cechę. Należy użyć generyków z ograniczeniem cechy.

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

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

Przyjmowanie FnMut

Jeśli funkcja musi modyfikować przechwycony stan, należy wymagać FnMut i oznaczyć parametr jako 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
}

Przyjmowanie FnOnce

Jeśli funkcja wywołuje domknięcie tylko raz i może pozwolić mu na zużycie wartości, należy wymagać 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);
}

Słowo kluczowe move

Słowo kluczowe move wymusza przejęcie przez domknięcie własności przechwyconych zmiennych zamiast ich pożyczania.

Jest to niezbędne, gdy domknięcie musi istnieć dłużej niż zakres, w którym je utworzono, na przykład w wątkach.

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

Jak Rust wybiera cechę

Nie wybierasz cechy ręcznie. Kompilator decyduje na podstawie treści domknięcia:

  • Tylko odczytuje → Fn
  • Modyfikuje → FnMut
  • Przenosi przechwyconą wartość → FnOnce
fn main() {
    let mut log = Vec::new();
    let mut record = |x: i32| log.push(x); // FnMut
    record(1);
    record(2);
    println!("{:?}", log);
}

Wybór właściwego ograniczenia

Zgodnie z ogólną zasadą:

  • Przyjmuj Fn, gdy wystarczy wywoływanie i odczytywanie.
  • Przyjmuj FnMut, gdy domknięcie modyfikuje stan.
  • Przyjmuj FnOnce, gdy wystarczy jedno wywołanie.

Wybierz najbardziej liberalne ograniczenie, które spełnia wymagania.

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));
}

Szybkie sprawdzenie

Dopasuj zachowanie domknięcia do jego cechy.

Podsumowanie

Trzy cechy domknięć:

  • Fn — pożycza niezmiennie, można wywoływać wielokrotnie.
  • FnMut — pożycza mutowalnie, może zmieniać stan.
  • FnOnce — przejmuje własność, można wywołać raz.

Kompilator wyprowadza cechę, a move wymusza przejęcie własności przechwytywanych wartości.

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

Często zadawane pytania

Czy lekcja „Fn, FnMut, FnOnce” jest bezpłatna?

Tak — pełny tekst „Fn, FnMut, FnOnce” jest dostępny za darmo tutaj w sieci. Aby ćwiczyć ją interaktywnie (wbudowany edytor kodu i tutor AI dostępny 24/7) i odblokować resztę kursu Learn Rust Coding, przejdź na CoddyKit PRO. Kurs Learn Rust Coding zawiera 4 lekcji w sumie.

Co nauczysz się w „Fn, FnMut, FnOnce”?

Cechy domknięć Ćwiczysz Learn Rust Coding z praktycznym kodem, który uruchamiasz bezpośrednio w przeglądarce, a tutor AI dostępny 24/7 odpowiada na Twoje pytania podczas pracy nad lekcją.

Czy potrzebuję doświadczenia, aby zacząć Learn Rust Coding?

Nie wymagamy żadnego doświadczenia. Learn Rust Coding w CoddyKit jest strukturyzowany dla początkujących i zaawansowanych użytkowników, więc możesz zacząć tutaj lub od początku i uczyć się w swoim tempie. To lekcja 4 z 4.

Ile czasu zajmuje lekcja „Fn, FnMut, FnOnce”?

Większość lekcji CoddyKit trwa około 5–10 minut. Każda lekcja to mały, interaktywny krok, dzięki czemu robisz systematyczne postępy i zawsze wracasz dokładnie do tego samego miejsca — na webie i w aplikacji.

Czy mogę pisać i uruchamiać kod w tej lekcji Learn Rust Coding?

Tak. Każda lekcja Learn Rust Coding zawiera wbudowany edytor kodu, więc piszesz i uruchamiasz prawdziwy kod bezpośrednio w przeglądarce i od razu otrzymujesz sprzężenie zwrotne od AI — bez konfiguracji na komputerze.

Wszystkie lekcje w tym kursie

  1. Definiowanie funkcji
  2. Wyrażenia i instrukcje
  3. Domknięcia
  4. Fn, FnMut, FnOnce
← Powrót do Learn Rust Coding