ByteNoteByteNote
Rust 所有权与内存管理完全指南

字节笔记本

2026年2月21日

Rust 所有权与内存管理完全指南

API中转
¥120

本文系统梳理 Rust 所有权、借用、生命周期等核心概念,帮助开发者理解 Rust 独特的内存管理机制。

一、为什么要这么设计?

内存安全问题是所有编程语言都要面对的难题:

  • C/C++:程序员手动管理,容易出错(微软统计 70% 安全漏洞来自内存问题)
  • Java/Python/Go:使用 GC 垃圾回收,安全但有性能损耗(Stop The World)
  • Rust:编译期通过规则推断,既安全又高性能,无 GC 运行时开销

二、所有权(Ownership)

三条核心规则

  1. 每个值只有一个所有者
  2. 所有者离开作用域,值被销毁
  3. 赋值或传参时,所有权转移(Move),原变量不能再用

代码示例

rust
let data = vec![1, 2, 3];
let data1 = data;  // 所有权转移给 data1
println!("{:?}", data);  // 报错!data 已经不能用了

Copy 语义

简单类型(整数、布尔等)赋值时自动复制,原变量仍可用:

rust
let v = 42;
let v1 = v;  // 整数实现 Copy trait,自动复制
println!("{}", v);  // 正常,v 还能用

三、借用(Borrowing)

为什么需要借用?

不想转移所有权,只是让函数"看看"数据,加 & 符号:

rust
fn sum(data: &Vec<u32>) -> u32 {
    data.iter().fold(0, |acc, x| acc + x)
}

借用规则(类似读写锁)

类型数量限制
只读借用 &多个不能修改
可变借用 &mut1个不能与只读借用共存

生命周期约束

借用不能比值活得更长:

rust
fn local_ref() -> &i32 {
    let a = 42;
    &a  // 报错!a 离开函数就销毁了
}

四、多所有者

场景

编译时无法解决的共享需求:DAG 图、多线程共享内存。

智能指针对照表

场景多所有者内部可变性
单线程RcRefCell
多线程ArcMutex / RwLock

Rc 引用计数

rust
let a = Rc::new(1);
let b = a.clone();  // 计数+1,数据不复制
let c = a.clone();  // 计数变成 3

RefCell 运行时检查

把借用检查推迟到运行时,违规时 panic:

rust
let data = RefCell::new(1);
*data.borrow_mut() = 2;  // 运行时检查

五、生命周期(Lifetime)

两种生命周期

  • 静态 'static:和进程一样长(全局变量、字符串字面量)
  • 动态 'a:作用域内存在,结束即销毁

为什么需要标注?

编译器看不到调用者上下文,不知道返回值跟谁绑定:

rust
// 编译器懵了:返回值跟 s1 还是 s2 有关?
fn max(s1: &str, s2: &str) -> &str { ... }

// 加上标注,告诉编译器约束关系
fn max<'a>(s1: &'a str, s2: &'a str) -> &'a str { ... }

自动推导规则

  1. 每个引用参数独立获得生命周期参数
  2. 只有一个引用输入,生命周期赋给所有输出
  3. &self,它的生命周期赋给所有输出

数据结构中的生命周期

rust
struct Employee<'a, 'b> {
    name: &'a str,
    title: &'b str,
    age: u8,
}

六、值的一生(内存视角)

创建时

  • :固定大小数据
  • :动态大小数据
  • Vec/String:栈上存"胖指针"(指针+容量+长度),堆上存数据

使用时

  • Copy/Move 都是浅拷贝(只复制栈上部分)
  • 效率很高,不必担心性能
  • 大数组应传引用避免开销

销毁时

  • 离开作用域自动调用 Drop trait
  • 递归释放所有字段
  • RAII:文件、Socket、锁等资源自动释放
  • 不需要手动 close(),不怕异常路径漏释放

七、五条规则总结

  1. 一个值同时只有一个所有者
  2. 实现 Copy trait 的类型,赋值传参自动复制
  3. 只读引用可以同时有多个
  4. 可变引用同时只能有一个,且和只读引用互斥
  5. 引用的生命周期不能超过值本身

八、核心收益

特性说明
无 GC运行时零开销,性能接近 C
内存安全编译期消除内存漏洞
无资源泄露RAII 自动管理所有资源
零成本抽象编译期解决,不付运行时代价

九、适用场景

Rust 最适合:

  • 操作系统
  • 嵌入式开发
  • 浏览器引擎
  • 网络基础设施
  • 高性能服务

如果只是脚本或业务后端,Python/Go 可能更省事。

十、一句话总结

Rust 用"单一所有权 + 借用规则 + 生命周期"这套编译期检查机制,在不引入 GC 的前提下,保证了内存和资源的安全管理。代价是写代码时遵守更严格的规则,收益是运行时零开销且没有内存安全漏洞。

分享: