内存安全不是靠强制规则堆出来的,而是编译器在编译期就亲手把内存错误的可能性掐死在摇篮里。Rust选择了一条看起来最笨重但最扎实的路——所有权系统、借用检查器和生命周期标注三位一体,构建出一套编译期即能验证的内存管理模型。这套模型把C++里需要开发者靠经验、靠最佳实践、靠静态分析工具才能规避的问题,直接变成了编译器报错。
理解所有权必须先扔掉GC语言和手动内存管理语言的经验惯性。Rust给堆上分配的每一块内存都指定唯一的所有者,所有者离开作用域,内存自动释放。这个规则简单到只有三条:每个值有且仅有一个所有者;所有权可以转移,但转移后原变量失效;所有者离开作用域时值被丢弃。
这个设计解决了悬垂指针和双重释放两大棘手问题。C++里一个指针被多个变量持有,谁该负责释放?什么时候释放?释放后其他变量变成野指针怎么办?Rust直接用所有权转移把这些问题抹掉了。看一段代码就清楚了:
fn main() {
let s1 = String::from("hello");
let s2 = s1; // s1的所有权转移给s2
// println!("{}", s1); // 编译错误:s1已经失效
println!("{}", s2);
}s1把所有权交给s2后,s1就不再持有那块堆内存的引用。编译器在编译期就能追踪到s1的失效状态,任何后续使用s1的代码都会触发编译错误。这不是运行时检查,而是编译期的静态分析。谷歌Android团队在将Rust引入Bluetooth栈后的实际数据显示,内存安全相关的漏洞占比从历史水平断崖式下降,这背后所有权机制贡献了关键力量。
借用机制让Rust在不破坏所有权规则的前提下实现灵活的数据访问。借用分为不可变借用和可变借用,借用检查器保证同一时刻要么存在多个不可变借用,要么只存在一个可变借用,两者不能共存。
<p>这个
评论
加载中...