每个学 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 标注,其实是把你脑子里模糊的假设,写成了可以被检查的契约。
被借用检查器折磨的日子终会过去。之后你会发现,它逼你写下的每一行代码,都是将来的你会感谢现在的你的那一行。