Mutación en Rust: ¿antes o después de los dos puntos? Análisis bajo el capó

Entrenador de Python en Línea para Principiantes

Aprende Python fácilmente sin sobrecargarte de teoría. Resuelve tareas prácticas con verificación automática, recibe pistas y escribe código directamente en el navegador, sin instalar nada.

Start Course

Introducción: el enigma de los dos «mut»

\n

Si alguna vez has escrito en Rust, seguramente has visto la extraña dualidad de la palabra clave mut. Puede estar tanto antes del nombre de la variable (let mut x = 5), como después de los dos puntos, junto al tipo (&mut T). A simple vista, un detalle, pero en Stack Overflow este tema ha acumulado miles de visitas. ¿Por qué? Porque detrás de este detalle se esconde una diferencia fundamental entre propiedad y referencia.

\n

En este artículo no solo responderemos a la pregunta «¿dónde colocar mut?». Investigaremos bajo el capó de Rust, analizaremos cómo el compilador maneja la mutabilidad y por qué esta diferencia es la clave para un trabajo seguro con la memoria. Si estás aprendiendo Rust o quieres comprender más a fondo su modelo de propiedad, estás en el lugar correcto.

\n\n

Parte principal: dos mundos — dos mut

\n

1. Primer mut: «Soy el dueño y puedo cambiar»

\n

Cuando escribes:

\n
let mut x = 42;\nx = 10; // ok\n
\n

le dices al compilador: «Creo una variable x que posee el valor 42, y permito cambiar este valor en el futuro». Sin mut, la variable es inmutable por defecto. Esta es una elección de diseño consciente de Rust: por defecto, seguridad; la mutación es un permiso explícito.

\n

Bajo el capó: el compilador asigna espacio en la pila (o en el montón, si es un Box) y marca la celda de memoria como «modificable». El verificador de préstamos (borrow checker) se asegurará de que no tengas referencias mutables e inmutables simultáneamente a esta memoria. Si no estuviera mut, cualquier intento de asignar un nuevo valor provocaría un error de compilación.

\n\n

2. Segundo mut: «Te doy las llaves, pero no te entrego la casa»

\n

Ahora un ejemplo con una referencia:

\n
let mut x = 42;\nlet y = &mut x; // referencia mutable a x\n*y = 100;\n
\n

Aquí &mut T no se trata de propiedad, sino de préstamo. Decimos: «Presto x a la variable y, y además le doy el derecho de modificarlo». x sigue siendo el propietario, pero transfiere temporalmente el control.

\n

Diferencia clave: mut después de los dos puntos se refiere al tipo de la referencia, no a la variable. No puedes escribir let &mut x = &y — es sintácticamente incorrecto. Rust distingue estrictamente:

\n
    \n
  • let mut x — variable propietaria modificable
  • \n
  • &mut T — referencia mutable a un valor de tipo T
  • \n
\n

Esta es precisamente la diferencia que confunde a los principiantes: visualmente, «mut» está en diferentes lugares, pero semánticamente, resuelve diferentes tareas.

\n\n

3. Por qué es importante: el verificador de préstamos

\n

Imagina que escribes una función que toma una referencia:

\n
fn increment(n: &mut i32) {\n    *n += 1;\n}\n\nfn main() {\n    let mut a = 5;\n    increment(&mut a);\n    println!("{}", a); // 6\n}\n
\n

Si hubiéramos escrito fn increment(n: &i32) (sin mut), no podríamos modificar n. Y si hubiéramos olvidado mut en a, no podríamos pasar una referencia mutable. El compilador de Rust te protege de cambios accidentales en los datos que podrían provocar condiciones de carrera o comportamiento indefinido.

\n

Bajo el capó: &mut T es una referencia única (exclusiva). En cualquier momento, solo puede existir una referencia mutable a los datos. Esta regla garantiza que nadie más lea los datos mientras los estás modificando. Puede haber tantas referencias inmutables como se desee — solo leen.

\n\n

4. Ejemplo real de la práctica: estructuras y métodos

\n

A menudo, la confusión surge al trabajar con métodos:

\n
struct Point {\n    x: i32,\n    y: i32,\n}\n\nimpl Point {\n    fn shift(&mut self, dx: i32, dy: i32) {\n        self.x += dx;\n        self.y += dy;\n    }\n}\n\nfn main() {\n    let mu                

Blogs

Book Recommendations