默认匹配 — 可以通过 mut x => {} 变量绑定,在里面临时修改捕获的值
fn main(){
let a = [[1, 2], [3, 4]];
// changed y == 6
// current y == 5
let y = 5;
match y {
mut y => {
y += 1;
println!("changed y == {y}");
}
}
println!("current y == {y}");
println!("hello rust.");
}
常量函数
const fn sq(n: i32) -> i32 {
n * n
}
const SQ_2: i32 = sq(2);
const SQ_3: i32 = sq(3);
// @ 常量函数在编译时计算其结果,结果必须是确定的,所以不能将随机数生成器编写为常量函数
// @ 常量函数不能包含 for 循环 (loop \ while 可以),也不能执行浮点数运算。
// 错误示例 1
const fn generate_random_number() -> i32 {
let mut rng = rand::thread_rng();
rng.gen_range(0..10)
}
// 错误示例 2
const fn calculate() -> i32 {
let mut res = 0;
for i in 0..10 { // error
res += 1;
if res > 10 {
break
}
}
return res;
}
// 正确允许的 代码示例 1
const fn calculate() -> i32 {
let mut res = 0;
while true {
res += 1;
if res > 10 {
break
}
}
return res;
}
// 正确允许的 代码示例 2
const fn calculate() -> i32 {
let mut res = 0;
loop {
res += 1;
if res > 10 {
break
}
}
return res;
}
可以通过在结构体定义上添加 #[derive(Copy, Clone)] 属性来为结构体实现 Copy trait, 但需要满足一些条件: 1,结构体的所有字段都必须实现了 Copy trait 2. 结构体不能实现 Drop trait
注意: 所有实现 Copy 类型都必须实现 Clone trait。 此外,Copy 是一个 标记 trait,它没有任何方法,它只是用来标记一个类型可以按位复制
clont trait 是数据被拷贝时 栈内存和堆内存会一起拷贝; 同时实现 Copy 和 Drop trait,可能会导致一些问题,例如重复释放内存或者重复关闭文件,
Drop trait 允许在值离开作用域后自动调用释放实现者实例拥有的资源;
数组、vec 等通过变量下标获取成员类型,不允许其中成员被移动,除非实现了 Copy
比如 let apple = menu[0];
let miko = mike.first; // 把第一个成员移走了
println!("{:?}", mike.second); // 第二个成员仍可以使用
println!("{:?}", mike.first); // 报错,第一个成员已经发生了 move
let simon = mike; // 报错,因为已有部分成员被移动了。
Drop 顺序 递归运行其所有字段的析构函数;
- 结构体的字段按
声明顺序删除 - 活动枚举变量的字段按 声明 顺序 删除
- 元组的字段 按 顺序删除
- 数组 或 所属切片的元素 从 第一个元素删除到最后一个元素
- 闭包 通过移动捕获的变量以未明确定义的顺序删除
- trait 对象运行基础类型的 析构 函数
不允许自己主动调用 drop 函数,如果想显式的释放资源,可以调用 mem::drop
rust 借用检查能力有限,它无法对程序中在函数之间传递和返回的各种引用的生命周期进行全局性 安全检查, 所以,需要开发者来对那些包含了输入和返回引用的函数进行声明周期参数的标注 来配合借用检查器来检查引用内存数据的有效性
输入引用的生命周期有效期,不能短于 输出(返回)引用的生命周期 有效期, 这意味着,引用所指向的内存数据在其生命周期内是有效的。