El shadowing es la posibilidad de declarar varias veces una variable con el mismo nombre en un mismo ámbito, donde la nueva variable "sombrea" a la anterior. En lenguajes sin shadowing (C, C++), la redefinición de una variable conduce a un error o comportamiento indefinido. Rust permite el shadowing y, además, cada variable es un objeto independiente con un nuevo tipo o valor. Esto es útil para transformaciones secuenciales de valores: por ejemplo, convertir una cadena directamente a un número sin pensar en nuevos nombres.
Problema: por un lado, mejora la legibilidad, previniendo la expansión de nombres de variables; por otro, complicando la depuración si se "sombrea" accidentalmente una variable en un bloque complejo y se obtiene un resultado inesperado.
Solución: El shadowing se utiliza solo donde realmente facilita la transformación y no perjudica la legibilidad. Cada "let var = ...;" crea una nueva variable, la antigua permanece inalterada fuera del bloque de declaración.
Ejemplo de código:
fn example() { let x = "42"; let x = x.parse::<i32>().unwrap(); println!("x: {}", x); // x: 42 }
Características clave:
¿Puede el shadowing cambiar la mutabilidad de una variable?
Sí, se puede "sombrear" una variable inmutable con una mutable y viceversa:
let x = 5; let mut x = x; x += 1;
¿Significa el shadowing que la variable anterior ha sido destruida?
No, los valores de la variable anterior viven hasta el final del bloque en el que fueron declarados, pero se vuelven inaccesibles por nombre.
¿Se puede usar shadowing dentro de un ciclo o dentro de bloques anidados?
Sí, cada ámbito permite declarar variables con los mismos nombres, y son variables diferentes.
En una función hay let result = expr1; ... let result = expr2;, donde los tipos son diferentes.
Ventajas:
Desventajas:
Se utiliza el shadowing solo para cambiar de tipo: primero se analiza una cadena, luego se asigna un número.
Ventajas:
Desventajas: