虽然其他语言中也有类似的特性,想到读者接触过的语言可能比较广泛,还是把Shadowing拿出来说一下,也必须说一下作用域这个基础知识。
作用域很简单,一个变量的作用域是从定义它之后开始生效,到所在层级的{}结束的时候停止。除非... 它被遮蔽(Shadowing)了。
看下面这个程序:
程序中有两个x,一个是在main函数里定义的x,我们叫它外面的x。一个是在{}里面又定义了一遍的x,我们叫它里面的x。
fn main() {
let x = 5; //外部x进入作用域
let x = x + 1; // 使用外部x
{
println!("Before inner X defined, the value of x is: {x}"); //外部x作用域中
let x = x * 2; //内部x开始进入作用域,外部x开始被遮蔽
println!("The value of x in the inner scope is: {x}"); //外部x被遮蔽,内部x在作用域中
}//内部x作用域终止,外部x作用域恢复
println!("The value of x is: {x}"); //外部x作用域中
} //外部x作用域停止
输出的结果是这样的:
$ cargo run
Compiling variables v0.1.0 (file:///projects/variables)
Finished dev [unoptimized + debuginfo] target(s) in 0.31s
Running `target/debug/variables`
Before inner X defined, the value of x is: 6
The value of x in the inner scope is: 12
The value of x is: 6
里面的x=12。
外面的x,初始化=5,加了1,在里面的x定义之前是6。在{}之后还等于6,不会受到 {}里面x 的影响。
x在{}里面重新定义了之后,之后,之后,(重要的事情说三遍),里面的x 就“遮蔽”(shadowing)了外面的x,此时,在{}里面使用x,就是里面的x了,所以打印出来的 inner scope 的 x = 12。
在里面的x定义中,中,中,中,即 let x = x * 2 这个语句中,等号后面的那个x还是外面的x的值 =6 哦。所以,里面的x才等于12。