Rust学习笔记 之 所有权规则

62 阅读2分钟

Rust 中的所有权系统是它内存安全的核心机制之一。Rust 通过三条所有权规则来管理内存,确保在编译时就能避免常见的内存错误,如空指针、悬垂指针和数据竞争。以下是 Rust 的三条所有权规则,并通过示例进行说明:

1. 每个值都有一个所有者

在 Rust 中,每个值都有一个变量作为它的所有者。这个变量负责管理该值的内存生命周期。

fn main() {
    let s = String::from("hello"); // s 是字符串 "hello" 的所有者
    println!("{}", s);
} // s 离开作用域,值被自动释放

在这个例子中,s 是字符串 "hello" 的所有者。当 s 离开作用域时,Rust 会自动调用 drop 函数来释放内存。

2. 同一时间只能有一个所有者

Rust 不允许一个值有多个所有者。这意味着你不能同时有两个变量指向同一个值。

fn main() {
    let s1 = String::from("hello");
    let s2 = s1; // s1 的所有权被移动到 s2
    // println!("{}", s1); // 这行会报错,因为 s1 不再拥有值
    println!("{}", s2); // 可以正常打印 s2
}

在这个例子中,s1 的所有权被移动到 s2,因此 s1 不再有效。如果你尝试使用 s1,编译器会报错。

3. 当所有者离开作用域时,值将被丢弃

当所有者变量离开其作用域时,Rust 会自动释放该值所占用的内存。

fn main() {
    {
        let s = String::from("hello"); // s 进入作用域
        println!("{}", s);
    } // s 离开作用域,值被自动释放
    // println!("{}", s); // 这行会报错,因为 s 已经离开作用域
}

在这个例子中,s 在内部作用域中有效,一旦离开这个作用域,s 就会被释放,后续无法再访问。

所有权与函数

当值传递给函数时,所有权也会发生转移。

fn take(s: String) {
    print!("{}", s);
}
fn main() {
    let s1 = String::from("hello");
    take(s1);
    // println!("{}", s); // 这行会报错,字符转的所有权已转移到函数内
}