所有权:每个内存对象都有一个主人变量。
变量绑定:将对象绑定给一个变量,先前的主人就失去所有权。
let s1 = String::from("hello"); // 变量绑定
let s2 = s1; // s1 对该字符串对象的所有权被绑定到 s2, s1 不再有效
关键字 mut
:声明可变变量。
let mut x = 5;
x = 6; // 可变
变量未使用警告:如果有变量在声明后从未使用,编译器将发出 #[warn(unused_variables)]
警告。
fn main() {
let x = 5; // 变量未使用警告
println!("Hello");
}
禁用变量未使用警告:
- 在变量名前使用下划线(如
let _x = 5
)禁用对该变量的未使用警告。 - 在文件头部使用
#![allow(unused)]
禁用对文件中所有变量的未使用警告。
同名变量遮蔽:
- 同一作用域内,后声明的变量将覆盖先声明的同名变量。
- 子作用域的变量将暂时覆盖父作用域的同名变量。
- 不同类型的变量也可以遮蔽,本质上,先后两个变量仅仅是命名相同。
// 变量遮蔽
fn main() {
let x = 5;
// x = 5
let x = x + 1;
// x 在 main 内遮蔽, x = 6
{
let x = x * 2;
// x 在块内遮蔽, x = 12
}
// 块的遮蔽解除, x = 6
// 不同类型的同名变量也可以遮蔽
let spaces = " ";
let spaces = spaces.len();
}
数组:
// 创建一个 f32 数组
let forty_twos = [42.0, 42f32, 42.0_f32];
// 打印数组中第一个值, 并控制小数位数为 2
println!("{:.2}", forty_twos[0]);
序列:
for i in 1..5 { } // 右开: [1, 5)
for i in 1..=5 { } // 右闭: [1, 5]
for i in 'a'..='z' { } // 不止是数值: ['a', 'z']
语句与表达式:
fn add_with_extra(x: i32, y: i32) -> i32 {
let x = x + 1; // 语句
let y = y + 5; // 语句
x + y // 表达式
}
fn main() {
let x = 5u32;
let y = { // 用一个块表达式为变量 y 赋值
let x_sq = x * x;
let x_cb = x_sq * x;
x + x_sq + x_cb // 表达式的值
};
let z = {
x * 2; // 分号让表达式变成了语句, 因此 z 不是 x*2, 而是 ()
};
}
发散函数:返回类型为 !
的函数。
fn dead_end() -> ! {
panic!("你已经到了穷途末路,崩溃吧!");
}
👉 2 所有权