Rust 周记:所有权与借用检查器

Rust 的内存管理不靠 GC,也不靠手动释放,而是所有权与借用检查器。记录几条让我印象最深的心得与误区。


最近集中学习 Rust,这里记录几个让我印象最深的点。

所有权(Ownership)

Rust 的内存管理不需要 GC,也不需要手动的 malloc/free,靠的是所有权规则

  1. 每个值都有一个所有者(owner)
  2. 同一时刻一个值只能有一个所有者
  3. 所有者离开作用域时,值被丢弃(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 值得多用)