Skip to content

Rust 所有权

Rust 的所有权(Ownership)是一套静态检查机制,用于在编译期追踪内存的创建、使用与销毁。通过所有权,Rust 保证内存安全与线程安全,同时避免了垃圾回收开销。所有权系统约束变量与资源之间的关系,遵循一组严格的规则来确保资源被唯一、可预测地管理。

基本规则

Rust 所有权要求同时满足如下三条规则:

  1. 每个值都有一个变量作为其所有者(owner)。
  2. 每个值在任意时刻只能有一个所有者。
  3. 所有者离开作用域时,值会被自动释放。

满足如上条件, Rust 能在编译期间判定资源生命周期,从而避免悬垂指针、双重释放等常见问题。

所有权转移

以下情况发生所有权移动:

rust
fn main() {
    // 赋值
    let a = String::from("hello");
    let b = a; // a 的所有权移动到 b, a不再可用
    
    // 函数调用
    let str = String::from("world");
    out(str); // str 的所有权移动到函数内, main函数内不再可用
}

fn out(content: String)
    println("content: {}", content);
}

如果实现了Copy特征, 会先拷贝原来变量或对象, 拷贝后的变量或对象发生所有权移动(不影响原变量或对象的使用)

借用

为了在不转移所有权的情况下使用数据,Rust 提供了借用机制,即以引用的方式访问值。借用分为:

  • 不可变引用&T):同一时刻可以有多个不可变引用。
  • 可变引用&mut T):同一时刻只能有一个可变引用,且不能与不可变引用共存。
rust
let mut s = String::from("rust");
let r1 = &s; // 不可变借用
let r2 = &s; // 还可以再借用
let r3 = &mut s; // 错误:同时存在不可变与可变借用

TIP

借用在编译期被检查,确保引用在其作用域内始终指向有效值且不会产生数据竞争。

切片

切片 (&[T]&str) 是通过借用实现的,允许按需读取数据的一部分,而不会复制底层内容。它以引用的形式存在,与借用规则一致。

rust
fn main() {
    let s = String::from("hello, world");
    let hello = &s[0..5]; // 取前5个字节
    let world = &s[7..12]; // 取"world"
    println!("{} {}", hello, world); // 输出: hello world
}

切片不会拥有数据的所有权,只是对原始数据的部分引用,因此使用切片时无需担心数据的复制和释放问题。

Released under the MIT License.