0Pricing
Learn Rust Coding · Lección

Fn, FnMut, FnOnce

Traits de closures

Fn, FnMut, FnOnce es una lección gratuita de Learn Rust Coding en CoddyKit. Esta es la lección 4 de 4. Puedes leer la lección completa abajo gratuitamente — luego la practicas en el navegador con un editor de código integrado y un tutor de IA 24/7. Forma parte de la ruta de aprendizaje de Learn Rust Coding, y tu progreso se sincroniza en la web y la app de CoddyKit. El curso de Learn Rust Coding incluye 4 lecciones en total.

Los traits de los closures

Cada closure implementa automáticamente uno o más de tres traits, según cómo utilice los valores capturados:

  • Fn — toma prestado de forma inmutable.
  • FnMut — toma prestado de forma mutable.
  • FnOnce — toma la propiedad y solo se puede llamar una vez.
fn main() {
    let x = 5;
    let show = || println!("x is {}", x); // implements Fn
    show();
    show();
}

Fn: préstamo inmutable

Un closure que solo lee los valores capturados implementa Fn. Puede llamarse muchas veces sin modificar nada.

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

FnMut: préstamo mutable

Un closure que modifica un valor capturado implementa FnMut. La propia variable del closure debe ser mut para poder llamarlo.

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

FnOnce: toma la propiedad

Un closure que mueve un valor capturado fuera del entorno implementa FnOnce. Solo se puede llamar una vez.

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

La jerarquía de traits

Los traits forman una jerarquía:

  • Todo Fn también es FnMut y FnOnce.
  • Todo FnMut también es FnOnce.

Por tanto, Fn es el más flexible y FnOnce, el menos flexible.

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

Pasar Fn a funciones

Una función puede aceptar un closure especificando el trait que necesita. Use genéricos con una restricción 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));
}

Aceptar FnMut

Si su función necesita modificar el estado capturado, exija FnMut y marque el parámetro como 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
}

Aceptar FnOnce

Cuando una función solo llama al closure una vez y puede permitirle consumir valores, exija 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);
}

La palabra clave move

La palabra clave move obliga a un closure a tomar la propiedad de las variables capturadas en lugar de tomarlas prestadas.

Esto es esencial cuando un closure debe vivir más tiempo que el ámbito donde se creó, por ejemplo, en hilos.

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

Cómo elige Rust el trait

Usted no elige el trait manualmente. El compilador decide según el cuerpo del closure:

  • Solo lee → Fn
  • Modifica → FnMut
  • Mueve un valor capturado → FnOnce
fn main() {
    let mut log = Vec::new();
    let mut record = |x: i32| log.push(x); // FnMut
    record(1);
    record(2);
    println!("{:?}", log);
}

Elegir la restricción adecuada

Como regla general:

  • Acepte Fn cuando solo necesite llamar al closure y leer valores.
  • Acepte FnMut cuando el closure modifique el estado.
  • Acepte FnOnce cuando baste con llamarlo una vez.

Elija la restricción más permisiva que se ajuste a sus necesidades.

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

Comprobación rápida

Relacione el comportamiento de un closure con su trait.

Resumen

Los tres traits de los closures:

  • Fn — toma prestado de forma inmutable y se puede llamar repetidamente.
  • FnMut — toma prestado de forma mutable y puede modificar el estado.
  • FnOnce — toma la propiedad y se puede llamar una vez.

El compilador infiere el trait; move fuerza la captura por propiedad.

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

Preguntas frecuentes

¿La lección «Fn, FnMut, FnOnce» es gratis?

Sí — el texto completo de «Fn, FnMut, FnOnce» es gratis para leer aquí en la web. Para practicarla de forma interactiva (editor de código integrado y tutor de IA 24/7) y desbloquear el resto del curso de Learn Rust Coding, actualiza a CoddyKit PRO. El curso de Learn Rust Coding incluye 4 lecciones en total.

¿Qué aprenderé en «Fn, FnMut, FnOnce»?

Traits de closures Practicas Learn Rust Coding con código real que ejecutas directamente en el navegador, y un tutor de IA 24/7 responde tus preguntas mientras trabajas en la lección.

¿Necesito experiencia previa para empezar Learn Rust Coding?

No se requiere experiencia previa. Learn Rust Coding en CoddyKit está estructurado para principiantes hasta estudiantes avanzados, así que puedes empezar aquí o desde el inicio y avanzar a tu ritmo. Esta es la lección 4 de 4.

¿Cuánto tiempo toma la lección «Fn, FnMut, FnOnce»?

La mayoría de las lecciones de CoddyKit toman alrededor de 5–10 minutos. Cada una es compacta e interactiva, así que avanzas constantemente y retomas exactamente por donde dejaste en la web y la app.

¿Puedo escribir y ejecutar código en esta lección de Learn Rust Coding?

Sí. Cada lección de Learn Rust Coding incluye un editor de código integrado, así que escribes y ejecutas código real directamente en tu navegador y obtienes retroalimentación instantánea de IA — sin configuración local necesaria.

Todas las lecciones de este curso

  1. Definición de funciones
  2. Expresiones y sentencias
  3. Closures
  4. Fn, FnMut, FnOnce
← Volver a Learn Rust Coding