Rust - Basic - 01 - Variables shadowing
Variables shadowing
Comprehension
在 Rust 中,如果一个变量( let
或者 let mut
) a
在后续中重复声明,那么这种行为被称为 shadowing 。
const
常量无法 shadowing- shadowing 可以有块(
{}
)作用域 - shadowing 可以在变量名相同的基础上,同时声明新的数据类型
Origin
https://doc.rust-lang.org/book/ch03-01-variables-and-mutability.html#shadowing
fn main() {
let x = 5;
let x = x + 1;
{
let x = x * 2;
println!("The value of x in the inner scope is: {}", x);
}
println!("The value of x is: {}", x);
}
This program first binds x
to a value of 5
. Then it shadows x
by repeating let x =
, taking the original value and adding 1
so the value of x
is then 6
. Then, within an inner scope, the third let
statement also shadows x
, multiplying the previous value by 2
to give x
a value of 12
. When that scope is over, the inner shadowing ends and x
returns to being 6
. When we run this program, it will output the following:
$ cargo run
Compiling variables v0.1.0 (file:///projects/variables)
Finished dev [unoptimized + debuginfo] target(s) in 0.31s
Running `target/debug/variables`
The value of x in the inner scope is: 12
The value of x is: 6
Shadowing is different from marking a variable as mut
, because we’ll get a compile-time error if we accidentally try to reassign to this variable without using the let
keyword. By using let
, we can perform a few transformations on a value but have the variable be immutable after those transformations have been completed.
The other difference between mut
and shadowing is that because we’re effectively creating a new variable when we use the let
keyword again, we can change the type of the value but reuse the same name. For example, say our program asks a user to show how many spaces they want between some text by inputting space characters, but we really want to store that input as a number:
let spaces = " ";
let spaces = spaces.len();
This construct is allowed because the first spaces
variable is a string type and the second spaces
variable, which is a brand-new variable that happens to have the same name as the first one, is a number type. Shadowing thus spares us from having to come up with different names, such as spaces_str
and spaces_num
; instead, we can reuse the simpler spaces
name. However, if we try to use mut
for this, as shown here, we’ll get a compile-time error:
let mut spaces = " ";
spaces = spaces.len();
The error says we’re not allowed to mutate a variable’s type:
$ cargo run
Compiling variables v0.1.0 (file:///projects/variables)
error[E0308]: mismatched types
--> src/main.rs:3:14
|
3 | spaces = spaces.len();
| ^^^^^^^^^^^^ expected `&str`, found `usize`
For more information about this error, try `rustc --explain E0308`.
error: could not compile `variables` due to previous error