En Rust no hay un recolector de basura clásico, por lo que se utilizan punteros inteligentes (smart pointers) para gestionar la propiedad de estructuras complejas. Los más comunes son:
Box<T> — asigna memoria para un objeto en el heap y transfiere la propiedad de esta. Se utiliza en casos donde el tamaño de los datos no se conoce en tiempo de compilación o se requiere un recurso único pero movible.
Rc<T> (Reference Counted) — conteo de referencias, permite que varias variables "compartan" la propiedad de datos inmutables (solo en un contexto de un solo hilo).
Arc<T> (Atomic Reference Counted) — también implementa el conteo de referencias, pero de forma atómica; es adecuado para programas multihilo.
RefCell<T> — proporciona propiedad "mutable interna" en tiempo de ejecución, permitiendo cambiar el contenido incluso a través de una referencia inmutable, pero solo en un hilo (¡no es seguro para hilos!).
Ejemplo:
use std::rc::Rc; let a = Rc::new(vec![1,2,3]); let b = Rc::clone(&a); // Ahora tanto a como b son propietarios de los mismos datos
¿Se puede usar Rc<T> en código multihilo si todos los hilos solo leen datos? Explique.
Respuesta: ¡No, no se puede! A pesar de que Rc<T> permite solo acceso inmutable a los datos, el propio contenedor Rc<T> no es seguro para hilos, ya que el conteo interno de referencias no está protegido contra condiciones de carrera. Para esto está destinado Arc<T> — su contador interno es seguro para hilos.
Ejemplo:
// ¡El siguiente código no se compilará! use std::thread; use std::rc::Rc; let five = Rc::new(5); for _ in 0..10 { let five = Rc::clone(&five); thread::spawn(move || { println!("{}", five); }); }
Historia
Historia
Historia
En un módulo de lógica de negocio, se utilizó RefCell<T> para organizar el acceso mutable a datos que también se pasaban a través de Arc<T> entre hilos. Pero intentar combinar RefCell<T> y Arc<T> llevó a condiciones de carrera y pánicos en tiempo de ejecución. Para una opción segura para hilos, se debió utilizar Mutex<T> o RwLock<T> en lugar de RefCell<T>.