Immutable vs const en Rust: ¿por qué se confunden incluso los desarrolladores experimentados?
\n\n¿Alguna vez has escrito en Rust y de repente te has preguntado: «Espera, declaré una variable con let, es inmutable. Y const también es como una constante. Entonces, ¿cuál es la diferencia?». Si es así, no estás solo. La pregunta «What is the difference between immutable and const variables in Rust?» en Stack Overflow ha acumulado miles de visitas. Y no es casualidad.
A primera vista, parece que tanto let x = 5 como const X: i32 = 5 hacen lo mismo: prohíben cambiar el valor. Pero en Rust, un lenguaje donde la seguridad de la memoria y el rendimiento son primordiales, el diablo está en los detalles. En 2025, entender estos detalles no es solo teoría, sino una necesidad para escribir código eficiente e idiomático.
En este artículo, aclararemos de una vez por todas: en qué se diferencia una variable inmutable de una constante, cuándo usar cada una y cuáles son las mejores prácticas vigentes en este momento. ¡Allá vamos!
\n\n1. Comprensión básica: ¿qué dice el compilador?
\n\nComencemos con lo más simple. En Rust, las variables son inmutables por defecto. Esto significa que después de asignar un valor, no puedes sobrescribirlo.
\n\nfn main() {\n let x = 5;\n // x = 6; // ¡Error! No se puede cambiar una variable inmutable\n println!("x = {}", x);\n}\n\nY aquí un ejemplo con una constante:
\n\nconst MAX_POINTS: u32 = 100_000;\n\nfn main() {\n println!("MAX_POINTS = {}", MAX_POINTS);\n}\n\nVisualmente, es similar. Pero el compilador de Rust las maneja de manera completamente diferente. Y aquí es donde se pone interesante.
\n\n1.1. Diferencia clave n.º 1: ¿dónde viven?
\n\n- \n
let— declara una variable. Existe en la pila (o en el montón si esBox,String, etc.) y tiene una dirección en memoria. Se puede tomar por referencia, pasar a funciones, mover. \n const— declara una constante. No tiene una dirección fija en memoria. El compilador inlinea (inserta) su valor directamente en el código en el lugar de uso. \n
Esta es una diferencia fundamental. const no es una variable, es un valor con nombre que se sustituye en tiempo de compilación.
fn main() {\n let x = 42;\n let y = &x; // Ok, tomamos una referencia a la variable\n\n const Z: i32 = 100;\n // let w = &Z; // ¡Error! La constante no tiene dirección, no se puede tomar referencia\n}\n\n2. Inmersión profunda: rendimiento y semántica
\n\nAhora que sabemos sobre el «lugar de residencia», analicemos otros aspectos importantes.
\n\n2.1. Tiempo de vida y ámbito
\nLas constantes viven en el ámbito global (o dentro de una función, pero con tiempo de vida static). Existen durante toda la ejecución del programa. Se pueden declarar fuera de una función y estarán disponibles en todas partes.
Las variables inmutables solo viven dentro del bloque (función, bucle, if). Tan pronto como el bloque termina, la memoria se libera.
const GLOBAL_CONST: i32 = 10;\n\nfn main() {\n let local_var = 20;\n // local_var solo vive dentro de main\n}\n// local_var ya no existe\n// GLOBAL_CONST sigue disponible\n\n2.2. Tipo y anotaciones
\nPara const es obligatorio especificar el tipo de dato. Para let, el compilador lo inferirá por sí mismo.
const PI: f64 = 3.14159; // Obligatorio: const NOMBRE: Tipo = valor;\nlet pi = 3.14159; // El compilador entenderá por sí mismo que es f64\n\n2.3. Cálculo en tiempo de compilación (CTFE)
\nEl valor de const debe calcularse en tiempo de compilación.