Introducción: el enigma de los dos «mut»
\nSi 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.
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\nParte principal: dos mundos — dos mut
\n1. Primer mut: «Soy el dueño y puedo cambiar»
\nCuando escribes:
\nlet mut x = 42;\nx = 10; // ok\n\nle 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.
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.
2. Segundo mut: «Te doy las llaves, pero no te entrego la casa»
\nAhora un ejemplo con una referencia:
\nlet mut x = 42;\nlet y = &mut x; // referencia mutable a x\n*y = 100;\n\nAquí &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.
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
let mut x— variable propietaria modificable \n&mut T— referencia mutable a un valor de tipo T \n
Esta es precisamente la diferencia que confunde a los principiantes: visualmente, «mut» está en diferentes lugares, pero semánticamente, resuelve diferentes tareas.
\n\n3. Por qué es importante: el verificador de préstamos
\nImagina que escribes una función que toma una referencia:
\nfn 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\nSi 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.
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.
4. Ejemplo real de la práctica: estructuras y métodos
\nA menudo, la confusión surge al trabajar con métodos:
\nstruct 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