====== 第5章:所有权系统 ======
===== 什么是所有权? =====
所有权(Ownership)是 Rust 最独特的特性,它让 Rust 无需垃圾回收器即可保证内存安全。所有权的三条规则:
1. Rust 中的每个值都有一个**所有者**变量
2. 同一时间只能有一个所有者
3. 当所有者离开作用域,值被自动释放
===== 所有权规则一:每个值只有一个所有者 ====
fn main() {
let s1 = String::from("hello");
let s2 = s1; // s1 的所有权转移给 s2
// println!("{}", s1); // 编译错误:s1 已被移动(moved)
println!("{}", s2); // 正常:s2 是所有者
}
这称为**移动(Move)**。移动后原变量失效,避免了双重释放。
===== Copy 类型 ====
标量类型实现了 ''Copy'' trait,赋值时是拷贝而非移动:
fn main() {
let x = 5;
let y = x; // x 仍然是有效的拷贝
println!("x={}, y={}", x, y); // 都能访问
// 实现 Copy 的类型:
// - 所有整数类型
// - 浮点类型
// - 布尔类型
// - 字符类型
// - 元组(仅包含 Copy 类型时)
}
===== 函数参数的所有权 ====
传递变量给函数也会转移所有权:
fn take_ownership(s: String) {
println!("我拥有了: {}", s);
} // s 在此释放
fn main() {
let s = String::from("hello");
take_ownership(s);
// println!("{}", s); // 编译错误:所有权已转移
}
===== 返回值转移所有权 ====
fn give_ownership() -> String {
let s = String::from("world");
s // 返回所有权给调用者
}
fn main() {
let s = give_ownership();
println!("{}", s); // 正常:s 现在拥有所有权
}
===== Clone:显式深拷贝 ====
如果确实需要复制堆上的数据,用 ''clone()'':
fn main() {
let s1 = String::from("hello");
let s2 = s1.clone(); // 深拷贝堆数据
println!("s1 = {}, s2 = {}", s1, s2); // 都能访问
}
注意:''clone()'' 是显式的,意味着开发者意识到这是昂贵的操作。
===== 栈与堆 ====
**栈(Stack)**:后进先出,快速。存储大小固定的数据。
**堆(Heap)**:慢速,大小未知或动态变化的数据。分配时返回指针。
fn main() {
// i32 大小固定(4字节),在栈上
let x: i32 = 42;
// String 大小可变,数据在堆上,指针在栈上
let s: String = String::from("hello");
// s 本身在栈上(指针+长度+容量)
// "hello" 数据在堆上
}
===== 本章小结 =====
* 所有权是 Rust 管理内存的核心机制
* 移动(Move)转移所有权,原变量失效
* ''Copy'' 类型赋值是拷贝,堆上的类型默认是移动
* ''clone()'' 显式进行深拷贝
* 所有权通过函数参数和返回传递