最近集中学习 Rust,这里记录几个让我印象最深的点。
所有权(Ownership)
Rust 的内存管理不需要 GC,也不需要手动的 malloc/free,靠的是所有权规则:
- 每个值都有一个所有者(owner)
- 同一时刻一个值只能有一个所有者
- 所有者离开作用域时,值被丢弃(drop)
fn main() {
let s1 = String::from("hello");
let s2 = s1; // s1 的所有权转移给 s2
// println!("{}", s1); // 编译错误:s1 已被移动
println!("{}", s2); // ok
}借用(Borrowing)
不想转移所有权时,可以用引用:
fn len(s: &String) -> usize {
s.len()
}
let s = String::from("hello");
let n = len(&s); // 借用,不移动
println!("{s} 的长度是 {n}");
规则:同一时刻要么有多个不可变借用,要么有一个可变借用,不能同时存在。
生命周期(Lifetimes)
生命周期是借用检查器用来防止悬垂引用的机制。
fn first<'a>(x: &'a str, _y: &str) -> &'a str {
x
}
'a 表示返回值的生命周期不短于参数 x。日常写代码大部分情况可以依赖编译器自动推断。
心得
- 与其与借用检查器"搏斗",不如先接受它——它大多时候是对的
- 用
clone()是在明确表达"这里存在成本",反而让代码意图更清晰 - Rust 的编译错误信息质量极高(
rustc --explain值得多用)