很早之前就打算学习一下Rust,写下第一篇帖子记录学习过程,主要是通过简单的代码示例探索一些Rust的特性
对于默认变量不可变
这个问题,从底下的两段代码可以看出来
fn main() {
let x = 5;
println!("The value of x is: {}", x);
x = 6;
println!("The value of x is: {}", x);
}
在这里运行的时候就会报错
error[E0384]: cannot assign twice to immutable variable `x`
--> src\main.rs:4:5
|
2 | let x = 5;
| -
| |
| first assignment to `x`
| help: consider making this binding mutable: `mut x`
3 | println!("The value of x is: {x}");
4 | x = 6;
| ^^^^^ cannot assign twice to immutable variable
这里就是标识这里对于变量x发生了改变,想要对x进行第二次赋值,但是x默认是不可变的变量,因此编译器无法通过编译,造成了报错的情况发生。
fn main() {
let mut x = 5;
println!("The value of x is: {}", x);
x = 6;
println!("The value of x is: {}", x);
}
在这段代码当中,我们通过添加
let mut
使得这个变量可变,从而完成对于变量x的赋值,假设我们在下面再次进行赋值
fn main() {
let mut x = 5;
println!("The value of x is: {}", x);
x = 6;
println!("The value of x is: {}", x);
x = 7;
println!("The value of x is: {}", x);
}
也是可以正常的进行编译与输出的
The value of x is: 5
The value of x is: 6
The value of x is: 7
下面再来进行一个更有趣的实验,我们来尝试一下下面的代码
fn main() {
let mut x = 5;
println!("The value of x is: {}", x);
let x = 6;
println!("The value of x is: {}", x);
x = 7;
println!("The value of x is: {}", x);
}
现在不是能够正常进行编译的
error[E0384]: cannot assign twice to immutable variable `x`
--> src\main.rs:6:5
|
4 | let x = 6;
| -
| |
| first assignment to `x`
| help: consider making this binding mutable: `mut x`
5 | println!("The value of x is: {}", x);
6 | x = 7;
| ^^^^^ cannot assign twice to immutable variable
为什么会出现这种错误呢?
答案是Rust特性在这里被使用了,那就是变量遮蔽(Shadowing)。
当使用let
关键字再次声明同名的变量时,新的变量会遮蔽(或隐藏)之前的变量。这是允许的,即使原来的变量是可变的,使用let
再次声明同名变量并不需要mut
关键字,因为实际上是在创建一个新的变量。
这里的关键点是,遮蔽允许你重新使用同一个名称,但每次使用let
都会创建一个新的、独立的变量。
再来看代码:
fn main() {
let mut x = 5;
println!("The value of x is: {}", x); // 这里 x 是 5
let x = 6;
println!("The value of x is: {}", x); // 现在新的 x 遮蔽了旧的 x,这里 x 是 6
x = 7; // 编译错误:因为这里的 x 是不可变的
println!("The value of x is: {}", x);
}
在第二次使用let x = 6;
时,实际上创建了一个新的不可变的变量x
,它遮蔽了之前的可变变量x
。因此,当你尝试执行x = 7;
时,会遇到编译错误,因为这个新的x
是不可变的。
如何修复这个错误?
如果想在之后修改x
的值,需要确保x
是可变的。
但是,如果想继续使用变量遮蔽(而不是保持原变量的可变性),只能对这个新的遮蔽变量重新赋值通过再次使用let
,如下所示:
fn main() {
let mut x = 5;
println!("The value of x is: {}", x); // 使用 {} 来插值变量
let x = 6;
println!("The value of x is: {}", x); // x 被遮蔽,现在是 6
let x = 7; // 再次遮蔽 x,现在 x 是 7
println!("The value of x is: {}", x);
}
这样的代码完全有效,它在这里展示了变量遮蔽的能力,允许重新绑定一个变量名给一个新的值,即使新旧变量的可变性不同。