第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 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()

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() 显式进行深拷贝
  • 所有权通过函数参数和返回传递

该主题尚不存在

您访问的页面并不存在。如果允许,您可以使用创建该页面按钮来创建它。

  • rust/所有权系统.txt
  • 最后更改: 2026/06/15 15:42
  • 张叶安