文章目录
变量
- Rust 支持声明可变的变量和不可变的变量,需要手动设定变量的可变性;
- 相较于其他语言的变量赋值,Rust 叫变量绑定;
不可变变量
设置变量 a 为字符串 “hello world”,相较于 go
的 var,在 rust 中使用 let,为了突出变量绑定的概念
let a = "hello world"
上述默认情况下,变量是不可变的,如下,编译会出问题,cannot assign twice to immutable variable。(无法对不可变的变量进行重复赋值)
fn main() {
let x = "abc";
println!("The value of x is: {}", x);
x = "def"; // 修改不可变的变量
println!("The value of x is: {}", x);
}
可变变量
可以通过 mut
关键字让变量变为可变 的,如下
fn main() {
let mut x = "abc"; // 加上 mut,x 为可变变量
println!("The value of x is: {}", x);
x = "def";
println!("The value of x is: {}", x);
}
使用下划线开头忽略未使用的变量
如果你创建了一个变量却不在任何地方使用它,Rust 通常会给你一个警告。但是有时创建一个不会被使用的变量是有用的。这时你希望告诉 Rust 不要警告未使用的变量,为此可以用下划线作为变量名的开头:
fn main() {
let _x = 5;
let y = 10;
}
使用 cargo run
运行下试试:
# cargo run
Compiling hello_world v0.1.0 (/opt/rust/hello_world)
warning: unused variable: `y`
--> src/main.rs:4:9
|
4 | let y = 10;
| ^ help: if this is intentional, prefix it with an underscore: `_y`
|
= note: `#[warn(unused_variables)]` on by default
warning: `hello_world` (bin "hello_world") generated 1 warning
Finished dev [unoptimized + debuginfo] target(s) in 0.35s
Running `target/debug/hello_world`
可以看到,两个变量都没有使用,但是编译器却独独给出了 y
未被使用的警告。
变量解构
let
表达式不仅仅用于变量的绑定,还能进行复杂变量的解构:
fn main() {
let (a, mut b): (bool,bool) = (true, false);
// a = true,不可变; b = false,可变
println!("a = {:?}, b = {:?}", a, b);
b = true;
assert_eq!(a, b);
}
解构式赋值
我们可以在赋值语句的左式中使用元组、切片和结构体模式。
struct Struct {
e: i32
}
fn main() {
let (a, b, c, d, e);
(a, b) = (1, 2);
// _ 代表匹配一个值,但是我们不关心具体的值是什么,因此没有是一个变量名而是使用了 _
[c, .., d, _] = [1, 2, 3, 4, 5];
Struct { e, .. } = Struct { e: 5 };
assert_eq!([1, 2, 1, 4, 5], [a, b, c, d, e]);
}
这种使用方式跟之前的 let
保持了一致性,但是 let
会重新绑定,而这里仅仅是对之前绑定的变量进行再赋值。
需要注意的是,使用 +=
的赋值语句还不支持解构式赋值。
变量和常量之间的差异
常量(constant)。与不可变变量一样,常量也是绑定到一个常量名且不允许更改的值,但是常量和变量之间存在一些差异:
- 常量不允许使用
mut
。常量不仅仅默认不可变,而且自始至终不可变,因为常量在编译完成后,已经确定它的值。 - 常量使用
const
关键字而不是let
关键字来声明,并且值的类型必须标注。
下面是一个常量声明的例子,其常量名为 MAX_POINTS
,值设置为 100,000
。(Rust 常量的命名约定是全部字母都使用大写,并使用下划线分隔单词,另外对数字字面量可插入下划线以提高可读性):
const MAX_POINTS: u32 = 100_000;
变量遮蔽(shadowing)
Rust 允许声明相同的变量名,在后面声明的变量会遮蔽掉前面声明的,如下所示:
fn main() {
let x = 5;
let x = x + 1;
println!("The value of x is: {}", x);
}
这个程序首先将数值 5
绑定到 x
,然后通过重复使用 let x =
来遮蔽之前的 x
,并取原来的值加上 1
,所以 x
的值变成了 6
。当运行此程序,将输出以下内容:
$ cargo run
...
The value of x is: 6