每个学 Rust 的人都有一段被借用检查器(borrow checker)按在地上摩擦的历史。这篇文章不讲语法条文,只讲一件事:所有权机制到底在解决什么问题。

它防的不是你,是时间

悬垂指针、迭代器失效、数据竞争——这些问题的共同点是:一块内存的存活时间,和它的使用者以为的存活时间不一致。GC 语言用运行时扫描抹平了这个问题,Rust 则选择把它提前到编译期,用所有权规则静态地证明“没有人会在内存释放后还拿着它的引用”。

三条规则,一种直觉

  • 每个值有且只有一个所有者;
  • 同一时刻,要么有任意多个不可变引用,要么只有一个可变引用;
  • 引用必须始终有效。

把它翻译成直觉:所有权是资源的“房产证”,借用是“参观证”,可变借用是“装修许可”——装修期间,谢绝参观。

fn main() {
    let mut log = String::from("编译错误");
    let reader = &log;        // 参观
    println!("{reader}");
    // reader 不再使用后,装修许可才发得出来
    log.push_str(",已修复");
    println!("{log}");
}

和编译器做队友

当你不再把报错当作对抗,而是当作一次免费的代码评审,Rust 的学习曲线会忽然变平。那些 lifetime 标注,其实是把你脑子里模糊的假设,写成了可以被检查的契约。

被借用检查器折磨的日子终会过去。之后你会发现,它逼你写下的每一行代码,都是将来的你会感谢现在的你的那一行。