Shadowing 是在同一作用域内重复定义同一名称的变量的能力,此时新变量 "遮蔽" 了先前的变量。在没有 shadowing 的语言(如 C、C++)中,重复定义变量会导致错误或未定义行为。Rust 允许 shadowing,并且每个变量都是独立的对象,具有新类型或新值。这在逐步转换值时非常方便——例如,可以将字符串直接转换为数字,而无需想出新名称。
问题:一方面——提高可读性,防止变量名称膨胀;另一方面——如果意外 "遮蔽" 了复杂块中的变量而导致意外结果,会使调试变得困难。
解决方案:Shadowing 仅在确实提高转换便利性且不降低可读性的情况下使用。每个 "let var = ...;" 创建新变量,旧变量在声明块之外保持不变。
代码示例:
fn example() { let x = "42"; let x = x.parse::<i32>().unwrap(); println!("x: {}", x); // x: 42 }
关键特性:
Shadowing 能否改变变量的可变性?
可以,能 "遮蔽" 不可变变量为可变变量,反之亦然:
let x = 5; let mut x = x; x += 1;
Shadowing 是否意味着先前的变量被销毁?
不是,先前变量的值在声明的块结束之前都存在,但通过名称变得不可访问。
可以在循环内部或嵌套块内部使用 shadowing 吗?
可以,每个作用域都允许使用相同名称声明变量,并且它们是不同的变量。
在一个函数中有 let result = expr1; ... let result = expr2;,而且类型不同。
优点:
缺点:
仅为更改类型使用 shadowing:首先解析字符串,然后分配数字。
优点:
缺点: