所有权(Ownership)是 Rust 最独特也最重要的特性。它使得 Rust 能够在没有垃圾回收器(GC)的情况下保证内存安全。 理解所有权,是掌握 Rust 的第一步。
为什么需要所有权
在传统语言中,内存管理通常有两种模式:手动管理(如 C/C++)或垃圾回收(如 Java、Go)。 手动管理容易出错,垃圾回收则带来运行时开销。Rust 通过所有权系统在编译期解决内存安全问题, 实现了零成本抽象。
三条核心规则
Rust 所有权系统基于以下三条简单规则:
- 每个值都有一个所有者(owner)。
- 同一时间只能有一个所有者。
- 当所有者离开作用域,值会被自动释放。
移动语义
在 Rust 中,赋值默认是"移动"(move)而非"复制"(copy):
let s1 = String::from("hello");
let s2 = s1; // s1 被移动到 s2
// println!("{}", s1); // 编译错误!s1 已失效
这确保了同一时间只有一个变量负责释放这块内存,避免了双重释放(double free)问题。
借用与引用
如果我们需要在不转移所有权的情况下使用值,可以使用引用(reference)。借用分为不可变借用和可变借用:
fn main() {
let mut s = String::from("hello");
change(&mut s);
println!("{}", s); // 正常工作,所有权未被转移
}
fn change(some_string: &mut String) {
some_string.push_str(", world");
}
生命周期
生命周期(Lifetime)是借用检查器的核心机制,它确保引用不会比被引用的数据活得更久。 编译器会自动推导大部分生命周期,但在函数返回引用时需要显式标注:
fn longest<'a>(x: &'a str, y: &'a str) -> &'a str {
if x.len() > y.len() { x } else { y }
}
总结
所有权系统看似严格,实际上它只是在编译期强制执行了良好的内存管理实践。 一旦熟悉这套规则,你会发现它能有效避免大量的内存相关 bug,同时保持高性能。