Introducción: "¿Y dónde están las variables globales?" — el primer shock del principiante en Rust
\n\nAcabas de empezar a estudiar Rust, escribiste un par de programas y de repente te das cuenta: necesitas que alguna variable sea accesible desde cualquier punto del código. En Python o JavaScript simplemente escribirías global_var = 42 en el nivel superior y listo. Pero en Rust... el compilador te mira con reproche y te da un error.
La pregunta "Is it possible to use global variables in Rust?" es una de las más populares en Stack Overflow. Y con razón. Rust, a diferencia de muchos lenguajes, no permite simplemente declarar una variable global. ¿Por qué? Porque la seguridad de memoria no es solo una palabra de moda, sino la base del lenguaje.
\n\nEn este artículo analizaremos todas las formas de trabajar con datos globales en Rust: desde constantes simples hasta almacenes seguros para hilos. Aprenderás cómo sortear las limitaciones del compilador sin sacrificar la seguridad, y cuándo las variables globales son un mal y cuándo una necesidad.
\n\n¿Por qué Rust prohíbe las variables globales "normales"?
\n\nAntes de buscar soluciones, entendamos el problema. En Rust rigen reglas estrictas de propiedad (ownership) y préstamo (borrowing). Una variable global que puede ser modificada desde cualquier hilo en cualquier momento es un camino directo a una condición de carrera (data race).
\n\nImagina: dos hilos intentan escribir diferentes valores en la misma variable global al mismo tiempo. El resultado es impredecible. En C++ o C esto lleva a un comportamiento indefinido. Rust garantiza que esto simplemente no se compilará.
\n\nPor lo tanto, el compilador nos exige especificar explícitamente:
\n- \n
- ¿La variable es inmutable? Usa
constostatic. \n - ¿La variable es mutable y se usa en un solo hilo? Usa
static mut(conunsafe). \n - ¿La variable es mutable y se usa en varios hilos? Usa
Mutex,RwLocko tipos atómicos. \n
Método 1: Constantes (const) — la opción más segura
\n\nSi tu "valor global" es en realidad una constante que nunca cambia, usa const:
const MAX_CONNECTIONS: u32 = 100;\nconst DATABASE_URL: &str = "postgresql://localhost:5432/mydb";\n\nfn main() {\n println!("Máximo de conexiones: {}", MAX_CONNECTIONS);\n}\n\nLas constantes en Rust no son solo variables. El compilador las inlinea en el lugar de uso. Es decir, durante la compilación, MAX_CONNECTIONS se reemplazará por el número 100. Esto es eficiente, pero significa que la constante no tiene una dirección fija en memoria. Si necesitas una ubicación en memoria (por ejemplo, para FFI), usa static.
Método 2: Variables estáticas (static)
\n\nSi necesitas una variable global con una dirección fija en memoria, usa static:
static APP_NAME: &str = "My Rust Application";\nstatic VERSION: u32 = 1;\n\nfn main() {\n println!("Iniciando {} versión {}", APP_NAME, VERSION);\n}\n\nPor defecto, las variables static son inmutables. Esto garantiza la seguridad en entornos multihilo. Pero, ¿qué pasa si necesitas modificar el estado global?
Método 3: Variables estáticas mutables (static mut) — cuidado, unsafe!
\n\nRust permite declarar una variable estática mutable con static mut. Pero hay un truco: cualquier lectura o escritura de dicha variable requiere un bloque unsafe.
static mut COUNTER: u32 = 0;\n\nfn increment() {\n unsafe {\n COUNTER += 1;\n }\n}\n\nfn main() {\n increment();\n unsafe {\n println!("Contador: {}", COUNTER);\n }\n}\n\nImportante: