Rust 大白话- <所有权、借用、引用>

Rust 语言最独特也最核心的特性就是它的内存管理方式,它通过"所有权"(Ownership)和"借用"(Borrowing)系统来确保内存安全,而不需要像 Go 那样依赖垃圾回收器。

1. 所有权 (Ownership)

你可以把所有权想象成你拥有一件物品的权利。在 Rust 中,每块数据都有一个"所有者"。这个所有者是唯一的,并且当所有者不再需要这块数据时(比如变量超出了它的作用范围),Rust 会自动帮你清理掉这块数据所占用的内存。

所有权的核心规则有三条:

  1. 每个值都有一个所有者。 就像你买了一本书,这本书就属于你。
  2. 在任何给定时间,一个值只能有一个所有者。 你不能同时把同一本书借给两个人,让他们都声称自己是这本书的唯一主人。
  3. 当所有者超出作用域时,值会被"丢弃"(内存被释放)。 当你不再需要这本书时,你会把它处理掉(比如卖掉、捐掉或扔掉),它所占用的空间就被释放了。
rust 复制代码
fn main() {
    let s1 = String::from("你好,Rust!"); // s1 现在是这串文本的所有者
    // println!("{}", s1); // 此时 s1 拥有所有权,可以正常使用

    let s2 = s1; // 所有权从 s1 转移到了 s2
    // println!("{}", s1); // 错误!s1 不再拥有所有权,不能再使用了 [1]
    println!("{}", s2); // s2 现在是所有者,可以正常使用 [1]
} // 当 s2 超出作用域时,它所拥有的数据("你好,Rust!")会被自动清理 [1]

2. 借用 (Borrowing)

如果每次使用数据都必须转移所有权,那会非常不方便。比如,你只是想让朋友帮你看看你的书,而不是把书送给他。这时,你就可以把书"借"给朋友。在 Rust 中,这就是"借用"的概念。

借用允许你临时访问一个值,而不需要获取它的所有权 。当你借用一个值时,你会得到一个"引用"(Reference),而不是拥有这个值本身。

借用的类型:

Rust 有两种类型的借用(或引用):

  • 不可变借用 (&T) :这就像你把书借给朋友看,他可以阅读书的内容,但不能在书上涂写或撕页。在 Rust 中,这意味着你可以读取被借用的数据,但不能修改它 。
  • 可变借用 (&mut T) :这就像你把书借给朋友,并允许他在书上做笔记或修改。在 Rust 中,这意味着你可以读取并修改被借用的数据 。
rust 复制代码
fn main() {
    let s = String::from("Hello"); // s 拥有所有权

    // 不可变借用
    let len = calculate_length(&s); // 我们把 s 的引用(&s)传递给函数
    println!("字符串 '{}' 的长度是 {}.", s, len); // s 仍然拥有所有权,可以继续使用 [1]

    // 可变借用
    let mut s_mut = String::from("Hello"); // s_mut 拥有所有权,并且是可变的
    change_string(&mut s_mut); // 我们把 s_mut 的可变引用(&mut s_mut)传递给函数
    println!("{}", s_mut); // s_mut 仍然拥有所有权,并且内容已被修改 [1]
}

fn calculate_length(s: &String) -> usize { // 接收一个不可变引用
    s.len() // 可以读取长度
} // s 在这里超出作用域,但因为它只是一个引用,所以它指向的数据不会被丢弃 [1]

fn change_string(s: &mut String) { // 接收一个可变引用
    s.push_str(", world!"); // 可以修改字符串内容
}

3. 借用规则 (Borrowing Rules)

为了确保内存安全,Rust 对借用施加了非常严格的规则,这些规则在编译时就会被检查:

  1. 在任何给定时间,你只能拥有以下两种情况之一:

    • 一个可变引用:就像你只能把书借给一个朋友,并允许他修改,这样就不会有两个人同时修改同一本书导致混乱的情况。
    • 任意数量的不可变引用:你可以把书复印很多份,借给很多朋友阅读,因为他们都不能修改原书,所以不会有冲突 。
  2. 引用必须始终有效:你不能有一个"悬垂引用"(dangling reference),即引用指向的内存已经被释放了。Rust 的借用检查器会确保引用不会比它所指向的数据活得更久 。

rust 复制代码
fn main() {
    let mut s = String::from("hello"); // s 是可变的,拥有所有权

    let r1 = &s; // 没问题,第一个不可变引用
    let r2 = &s; // 没问题,第二个不可变引用
    println!("{} 和 {}", r1, r2); // r1 和 r2 在这里被使用,之后就不再使用了

    // let r3 = &mut s; // 错误!不能在不可变引用 (r1, r2) 仍然活跃时创建可变引用 [1]
    // 因为 r1 和 r2 在上一行 println! 之后就不再使用了,所以现在可以创建可变引用
    let r3 = &mut s; // 没问题,现在可以创建可变引用了 [1]
    r3.push_str(", world!");
    println!("{}", r3);
}

总结

  • 所有权:数据有且只有一个所有者,所有者负责数据的生命周期和内存清理。

  • 借用:允许你临时访问数据而不转移所有权,通过"引用"实现。

  • 引用 :分为不可变引用(&T,只读)和可变引用(&mut T,可读写)。

  • 借用规则:严格限制了引用的使用方式,确保在编译时就避免了数据竞争和内存安全问题。

vibe coding

相关推荐
RustFS13 小时前
操作 MinIO 平替之 RustFS 存储桶的三种方法
rust·aws
林太白16 小时前
Rust-搞定图片上传功能
前端·后端·rust
维维酱1 天前
一、macOS 开发环境准备
rust
Hello.Reader2 天前
Rust × Elasticsearch官方 `elasticsearch` crate 上手指南
elasticsearch·rust·jenkins
林太白2 天前
Rust知识篇05-所有权和借用
前端·后端·rust
林太白2 天前
Rust知识篇04-函数
前端·后端·rust
林太白2 天前
Rust知识篇03-字符、布尔、单元类型、输出、语句表达式
前端·后端·rust
林太白2 天前
Rust搜索优化
前端·后端·rust