Learn Rust Coding · Leçon

Fn, FnMut, FnOnce

Traits des fermetures

Leçon 4 sur 413 étapes

Fn, FnMut, FnOnce est une leçon Learn Rust Coding gratuite sur CoddyKit. Ceci est la leçon 4 sur 4. Tu peux lire la leçon complète ci-dessous gratuitement — puis la pratiquer en direct dans le navigateur avec un éditeur de code intégré et un tuteur IA 24/7. Elle fait partie du parcours d'apprentissage Learn Rust Coding, et ta progression se synchronise sur le web et l'application CoddyKit. Le cours Learn Rust Coding comprend 4 leçons au total.

Les traits des fermetures

Toute fermeture implémente automatiquement un ou plusieurs des trois traits suivants, selon la manière dont elle utilise les valeurs capturées :

  • Fn — emprunte de manière immuable.
  • FnMut — emprunte de manière mutable.
  • FnOnce — prend possession, peut être appelée une seule fois.
fn main() {
    let x = 5;
    let show = || println!("x is {}", x); // implements Fn
    show();
    show();
}

Fn : emprunt immuable

Une fermeture qui lit uniquement les valeurs capturées implémente Fn. Elle peut être appelée de nombreuses fois sans rien modifier.

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

FnMut : emprunt mutable

Une fermeture qui modifie une valeur capturée implémente FnMut. La variable de fermeture elle-même doit être mut pour pouvoir l'appeler.

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

FnOnce : prend possession

Une fermeture qui déplace une valeur capturée hors de l'environnement implémente FnOnce. Elle ne peut être appelée qu'une seule fois.

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

La hiérarchie des traits

Les traits forment une hiérarchie :

  • Tout Fn est également FnMut et FnOnce.
  • Tout FnMut est également FnOnce.

Fn est donc le plus flexible et FnOnce le moins flexible.

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

Passer Fn à des fonctions

Une fonction peut accepter une fermeture en indiquant le trait dont elle a besoin. Utilisez des génériques avec une contrainte de trait.

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

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

Accepter FnMut

Si votre fonction doit modifier un état capturé, exigez FnMut et marquez le paramètre avec 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
}

Accepter FnOnce

Lorsqu'une fonction n'appelle la fermeture qu'une seule fois et peut lui permettre de consommer des valeurs, exigez 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);
}

Le mot-clé move

Le mot-clé move force une fermeture à prendre la possession des variables capturées au lieu de les emprunter.

C'est essentiel lorsqu'une fermeture doit continuer à exister au-delà de la portée où elle a été créée, par exemple dans des fils d'exécution.

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

Comment Rust choisit le trait

Vous ne choisissez pas le trait manuellement. Le compilateur décide en fonction du corps de la fermeture :

  • Lit uniquement → Fn
  • Modifie → FnMut
  • Déplace une valeur capturée → FnOnce
fn main() {
    let mut log = Vec::new();
    let mut record = |x: i32| log.push(x); // FnMut
    record(1);
    record(2);
    println!("{:?}", log);
}

Choisir la bonne contrainte

En règle générale :

  • Acceptez Fn lorsque vous avez seulement besoin d'appeler et de lire.
  • Acceptez FnMut lorsque la fermeture modifie l'état.
  • Acceptez FnOnce lorsqu'un seul appel suffit.

Choisissez la contrainte la plus permissive qui convient.

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

Vérification rapide

Associez le comportement d'une fermeture à son trait.

Récapitulatif

Les trois traits des fermetures :

  • Fn — emprunte de manière immuable et peut être appelée plusieurs fois.
  • FnMut — emprunte de manière mutable et peut modifier son état.
  • FnOnce — prend la propriété et ne peut être appelée qu'une seule fois.

Le compilateur déduit le trait ; move force la capture par propriété.

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

Apprends Rust avec un tuteur IA — gratuit

Écris et exécute du vrai code dans ton navigateur, obtiens de l'aide instantanée d'un tuteur IA disponible 24h/24, et reprends là où tu t'es arrêté sur le web ou dans l'app.

Cours
39
Leçons
144

Questions Fréquemment Posées

La leçon « Fn, FnMut, FnOnce » est-elle gratuite ?

Oui — le texte complet de « Fn, FnMut, FnOnce » est gratuit à lire ici sur le web. Pour la pratiquer de manière interactive (un éditeur de code intégré et un tuteur IA 24/7) et déverrouiller le reste du cours Learn Rust Coding, passe à CoddyKit PRO. Le cours Learn Rust Coding comprend 4 leçons au total.

Qu'est-ce que j'apprendrai dans « Fn, FnMut, FnOnce » ?

Traits des fermetures Tu pratiques Learn Rust Coding avec du code pratique que tu exécutes directement dans le navigateur, et un tuteur IA 24/7 répond à tes questions au fur et à mesure que tu avances dans la leçon.

Dois-je avoir de l'expérience pour commencer Learn Rust Coding ?

Aucune expérience préalable n'est requise. Learn Rust Coding sur CoddyKit est structuré pour les débutants jusqu'aux apprenants avancés, donc tu peux commencer ici ou depuis le début et avancer à ton rythme. Ceci est la leçon 4 sur 4.

Combien de temps prend la leçon « Fn, FnMut, FnOnce » ?

La plupart des leçons CoddyKit prennent environ 5–10 minutes. Chacune est courte et interactive, tu progresses régulièrement et tu repiques exactement où tu t'es arrêté sur le web et l'app.

Peux-tu écrire et exécuter du code dans cette leçon Learn Rust Coding ?

Oui. Chaque leçon Learn Rust Coding inclut un éditeur de code intégré, tu écris et exécutes du vrai code directement dans ton navigateur et tu reçois des retours IA instantanés — aucune configuration locale requise.

Toutes les leçons de ce cours

  1. Définition de fonctions
  2. Expressions et instructions
  3. Fermetures
  4. Fn, FnMut, FnOnce
← Retour à Learn Rust Coding