0Pricing
Learn Rust Coding · Lección

Mover datos a los hilos

Use correctamente los cierres move

Mover datos a los hilos es una lección gratuita de Learn Rust Coding en CoddyKit. Esta es la lección 2 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 closures capturan el entorno

Un closure que se pasa a thread::spawn puede usar variables del ámbito circundante. De forma predeterminada, Rust las toma prestadas.

Sin embargo, un hilo creado puede vivir más que la función que lo creó, por lo que un préstamo normal no es seguro. Rust lo rechaza en tiempo de compilación.

El problema de los préstamos

Si un hilo toma prestada una variable local, el compilador no puede demostrar que la variable vivirá el tiempo suficiente. El hilo podría seguir ejecutándose después de que se elimine la variable.

El código siguiente no compila porque el closure solo toma prestado data.

use std::thread;

fn main() {
    let data = vec![1, 2, 3];
    // ERROR: closure may outlive `data`
    let h = thread::spawn(|| {
        println!("{:?}", data);
    });
    h.join().unwrap();
}

La palabra clave move

Agregar move antes del closure lo obliga a tomar la propiedad de las variables capturadas. Estas se mueven al hilo.

Ahora el hilo es propietario de los datos, por lo que se garantiza que seguirán siendo válidos durante toda la vida del hilo.

use std::thread;

fn main() {
    let data = vec![1, 2, 3];
    let h = thread::spawn(move || {
        println!("{:?}", data);
    });
    h.join().unwrap();
}

La propiedad se transfiere

Una vez que un valor se mueve a un hilo, el ámbito original ya no puede usarlo. La propiedad se ha transferido.

Intentar usar data en main después del movimiento produciría un error de compilación. El hilo es ahora el único propietario.

use std::thread;

fn main() {
    let data = vec![1, 2, 3];
    let h = thread::spawn(move || println!("{:?}", data));
    // println!("{:?}", data); // ERROR: value moved
    h.join().unwrap();
}

Mover tipos Copy

Los tipos que implementan Copy, como los enteros, se copian en lugar de moverse. El closure obtiene su propia copia.

Por eso, después de que un closure move capture un número, todavía puede usar el original en main.

use std::thread;

fn main() {
    let n = 42;
    let h = thread::spawn(move || {
        println!("thread sees {}", n);
    });
    println!("main still sees {}", n);
    h.join().unwrap();
}

Send: transferencia segura

Un tipo solo puede moverse a otro hilo si implementa el trait Send. Send significa que es seguro transferir su propiedad entre hilos.

La mayoría de los tipos son Send automáticamente. Algunos, como Rc, no lo son, y el compilador rechazará su movimiento.

Rc no implementa Send

Rc es un contador de referencias para un solo hilo. Su contador no está protegido frente a actualizaciones simultáneas, por lo que no implementa Send.

Intentar mover un Rc a un hilo no compila. En la lección siguiente usará Arc en su lugar.

use std::rc::Rc;
use std::thread;

fn main() {
    let r = Rc::new(5);
    // ERROR: `Rc<i32>` cannot be sent between threads safely
    let h = thread::spawn(move || println!("{}", r));
    h.join().unwrap();
}

Mover varios valores

Un solo closure move puede capturar varias variables a la vez. Todas se mueven al hilo.

Esto resulta práctico cuando un worker necesita tanto una entrada como una etiqueta.

use std::thread;

fn main() {
    let label = String::from("sum");
    let nums = vec![1, 2, 3, 4];
    let h = thread::spawn(move || {
        let total: i32 = nums.iter().sum();
        println!("{} = {}", label, total);
    });
    h.join().unwrap();
}

Clonar antes de mover

Si tanto el hilo como la función principal necesitan un valor, clónelo primero. Entregue una copia al hilo y conserve la otra.

Clonar copia los datos, de modo que cada lado es propietario de un valor independiente.

use std::thread;

fn main() {
    let original = String::from("hello");
    let for_thread = original.clone();
    let h = thread::spawn(move || println!("thread: {}", for_thread));
    println!("main: {}", original);
    h.join().unwrap();
}

Devolver los datos movidos

Un hilo que es propietario de datos movidos puede devolverlos y transferir de nuevo la propiedad al padre mediante join.

Este patrón mueve los datos al hilo, los procesa y después mueve el resultado hacia fuera.

use std::thread;

fn main() {
    let mut v = vec![3, 1, 2];
    let h = thread::spawn(move || {
        v.sort();
        v
    });
    let sorted = h.join().unwrap();
    println!("{:?}", sorted);
}

Por qué se necesita move

Sin move, el borrow checker supone que el closure toma los datos prestados. Como los hilos creados no tienen un límite de vida fijo vinculado a quien los llama, los préstamos no son seguros.

La palabra clave move convierte los préstamos en transferencias de propiedad y satisface el requisito 'static de spawn.

Comprobación rápida

Compruebe su comprensión de cómo mover datos a los hilos.

Resumen

Ha aprendido que los closures de los hilos deben ser propietarios de los datos que usan; esto se consigue con la palabra clave move.

Mover transfiere la propiedad, mientras que los tipos Copy se copian. El trait Send indica qué se puede transferir de forma segura, y Rc no implementa Send.

A continuación compartirá datos entre hilos mediante Arc y Mutex.

Preguntas frecuentes

¿La lección «Mover datos a los hilos» es gratis?

Sí — el texto completo de «Mover datos a los hilos» 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 «Mover datos a los hilos»?

Use correctamente los cierres move 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 2 de 4.

¿Cuánto tiempo toma la lección «Mover datos a los hilos»?

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. Crear hilos
  2. Mover datos a los hilos
  3. Compartir con Arc y Mutex
  4. Unir hilos y recopilar resultados
← Volver a Learn Rust Coding