0Pricing
Learn Rust Coding · Lección

Mutabilidad interior: RefCell y Cell

Aprenda sobre `RefCell` y `Cell` para la mutabilidad interior, que permiten acceder de forma mutable a los datos mediante una referencia inmutable, de manera segura.

Mutabilidad interior: RefCell y Cell es una lección gratuita de Learn Rust Coding en CoddyKit. Esta es la lección 2 de 3. 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 3 lecciones en total.

¿Qué es la mutabilidad interior?

En Rust, las reglas de borrowing normalmente impiden tener una referencia mutable a unos datos si ya tiene una referencia inmutable a ellos. Esto garantiza la seguridad de los datos.

La mutabilidad interior es un patrón de diseño que permite modificar datos incluso cuando solo tiene una referencia inmutable a ellos. Es como una excepción controlada a las reglas habituales de Rust, utilizada en situaciones específicas.

`Cell<T>`: para tipos Copy

El tipo Cell<T> proporciona mutabilidad interior para tipos que implementan el trait Copy (como enteros, booleanos y caracteres). Funciona reemplazando el valor contenido.

  • get(): devuelve una copia del valor contenido en Cell.
  • set(value): reemplaza el valor contenido en Cell por uno nuevo.

Es una solución sencilla y eficiente para datos pequeños que se pueden copiar.

Usar `Cell` para actualizar valores

Aquí tiene un ejemplo básico de Cell. Observe que podemos cambiar el valor contenido en Cell aunque Cell se haya declarado como inmutable.

use std::cell::Cell;

fn main() {
  let my_num = Cell::new(10);
  println!("Initial value: {}", my_num.get());

  my_num.set(20);
  println!("Updated value: {}", my_num.get());

  let x = &my_num;
  x.set(30); // Still works via immutable reference!
  println!("Via immutable ref: {}", my_num.get());
}

`RefCell<T>`: para tipos que no son Copy

Cuando necesita mutabilidad interior para tipos que no implementan Copy (como String, Vec o structs personalizados), debe usar RefCell<T>.

RefCell permite obtener referencias mutables a los datos internos, pero aplica las reglas de borrowing de Rust en tiempo de ejecución, no en tiempo de compilación.

El borrowing en tiempo de ejecución de `RefCell`

RefCell proporciona métodos que devuelven punteros inteligentes:

  • borrow(): devuelve un Ref (un puntero inteligente inmutable). Puede tener varios borrowings inmutables a la vez.
  • borrow_mut(): devuelve un RefMut (un puntero inteligente mutable). Solo puede tener un borrowing mutable a la vez.

Si infringe estas reglas en tiempo de ejecución, su programa ejecutará panic!.

Usar `RefCell` (borrowing inmutable)

Aquí usamos borrow() para obtener una referencia inmutable al String contenido en RefCell. Podemos imprimir su contenido.

use std::cell::RefCell;

fn main() {
  let my_string_cell = RefCell::new(String::from("Hello"));

  let s1 = my_string_cell.borrow();
  println!("Value: {}", *s1); // Dereference Ref to get String

  let s2 = my_string_cell.borrow(); // Multiple immutable borrows are fine
  println!("Another value: {}", *s2);
}

Usar `RefCell` (borrowing mutable)

Ahora obtengamos una referencia mutable usando borrow_mut(). Esto nos permite modificar el String. Tenga en cuenta que, una vez que s_mut está en el ámbito, no se permiten otros borrowings, ni mutables ni inmutables.

use std::cell::RefCell;

fn main() {
  let my_string_cell = RefCell::new(String::from("World"));

  { // Scope for the mutable borrow
    let mut s_mut = my_string_cell.borrow_mut();
    s_mut.push_str(", Rust!");
  }
  // s_mut is out of scope here, so we can borrow again

  let s_final = my_string_cell.borrow();
  println!("Final value: {}", *s_final);
}

El panic en tiempo de ejecución de `RefCell`

Si intenta obtener un borrowing mutable mientras otro borrowing mutable (o cualquier borrowing inmutable) está activo, RefCell hará que su programa ejecute panic! en tiempo de ejecución. Esto evita la corrupción de datos.

¡Ejecute este código para verlo en acción! Se bloqueará con un error de «borrow already in use».

use std::cell::RefCell;

fn main() {
  let my_value = RefCell::new(vec![1, 2, 3]);

  let _first_mut_borrow = my_value.borrow_mut();
  println!("First mutable borrow is active.");

  // This line will cause a runtime panic!
  // Try commenting it out to see the program run successfully.
  let _second_mut_borrow = my_value.borrow_mut();

  println!("This line will not be reached.");
}

Resumen de `Cell` frente a `RefCell`

La elección entre Cell y RefCell depende del tipo de datos y de cómo necesite trabajar con ellos:

  • Cell<T>: úselo para tipos que implementan Copy. Reemplaza el valor completo y, por lo general, es más sencillo y ofrece un mejor rendimiento.
  • RefCell<T>: úselo para tipos que no implementan Copy. Proporciona referencias a los datos internos y aplica las reglas de borrowing en tiempo de ejecución, lo que permite mutaciones más complejas.

Comprobación rápida: ¿Cell o RefCell?

Tiene un struct que debe almacenar un contador mutable (u32) y una lista mutable de nombres (Vec<String>), y ambos deben actualizarse a través de una referencia inmutable al struct. ¿Qué tipos de mutabilidad interior usaría para cada campo?

Repaso: mutabilidad interior

Ha aprendido sobre el patrón de mutabilidad interior de Rust, que permite modificar datos a través de una referencia inmutable de forma controlada y segura.

  • Cell<T>: para tipos Copy; reemplaza el valor interno.
  • RefCell<T>: para tipos que no son Copy; proporciona referencias mutables e inmutables comprobadas en tiempo de ejecución.
  • Infringir las reglas de RefCell provoca un panic en tiempo de ejecución, lo que garantiza la seguridad.

Estos tipos son fundamentales en patrones como los objetos simulados, las referencias circulares o los casos en los que una referencia inmutable compartida necesita realizar un seguimiento del estado interno.

Preguntas frecuentes

¿La lección «Mutabilidad interior: RefCell y Cell» es gratis?

Sí — el texto completo de «Mutabilidad interior: RefCell y Cell» 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 3 lecciones en total.

¿Qué aprenderé en «Mutabilidad interior: RefCell y Cell»?

Aprenda sobre `RefCell` y `Cell` para la mutabilidad interior, que permiten acceder de forma mutable a los datos mediante una referencia inmutable, de manera segura. 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 3.

¿Cuánto tiempo toma la lección «Mutabilidad interior: RefCell y Cell»?

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. Punteros inteligentes Box, Rc y Arc
  2. Mutabilidad interior: RefCell y Cell
  3. Concurrencia sin miedo con hilos
← Volver a Learn Rust Coding