m02-资源管理Skill m02-resource

Rust语言智能指针与资源管理指南。本技能详细讲解了Box、Rc、Arc、Weak、RefCell、Cell等智能指针的核心概念、选择决策流程、常见错误及反模式。涵盖所有权模型、线程安全、循环引用、堆分配、RAII、Drop trait等关键词,帮助开发者根据单线程/多线程、单一/共享所有权、是否存在循环引用等场景,做出正确的资源管理决策,避免内存泄漏和运行时错误。

后端开发 0 次安装 0 次浏览 更新于 2/27/2026

name: m02-resource description: “关键:用于智能指针和资源管理。触发词:Box、Rc、Arc、Weak、RefCell、Cell、智能指针、堆分配、引用计数、RAII、Drop、应该用Box还是Rc、何时用Arc vs Rc、智能指针、引用计数、堆分配” user-invocable: false

资源管理

第1层:语言机制

核心问题

这个资源需要什么样的所有权模式?

在选择智能指针之前,先理解:

  • 所有权是单一的还是共享的?
  • 访问是单线程的还是多线程的?
  • 是否存在潜在的循环引用?

错误 → 设计问题

错误 不要只是说 而是应该问
“需要堆分配” “用Box” 为什么不能放在栈上?
Rc内存泄漏 “用Weak” 循环引用在设计中是必要的吗?
RefCell panic “用try_borrow” 运行时检查是正确的方法吗?
抱怨Arc开销 “接受它” 真的需要多线程访问吗?

思考提示

在选择智能指针之前:

  1. 所有权模型是什么?

    • 单一所有者 → Box 或 拥有所有权的值
    • 共享所有权 → Rc/Arc
    • 弱引用 → Weak
  2. 线程上下文是什么?

    • 单线程 → Rc, Cell, RefCell
    • 多线程 → Arc, Mutex, RwLock
  3. 存在循环引用吗?

    • 是 → 其中一个方向必须是 Weak
    • 否 → 常规的 Rc/Arc 即可

向上追溯 ↑

当指针选择不明确时,追溯到设计:

"我应该用 Arc 还是 Rc?"
    ↑ 问:这个数据是否跨线程共享?
    ↑ 检查:m07-concurrency (线程模型)
    ↑ 检查:domain-* (性能约束)
情况 追溯到 问题
Rc vs Arc 困惑 m07-concurrency 并发模型是什么?
RefCell panic m03-mutability 内部可变性在这里合适吗?
内存泄漏 m12-lifecycle 清理应该在哪里发生?

向下推导 ↓

从设计到实现:

"需要单一所有者的堆数据"
    ↓ 使用:Box<T>

"需要共享不可变数据 (单线程)"
    ↓ 使用:Rc<T>

"需要共享不可变数据 (多线程)"
    ↓ 使用:Arc<T>

"需要打破引用循环"
    ↓ 使用:Weak<T>

"需要共享可变数据"
    ↓ 单线程:Rc<RefCell<T>>
    ↓ 多线程:Arc<Mutex<T>> 或 Arc<RwLock<T>>

快速参考

类型 所有权 线程安全 使用场景
Box<T> 单一 堆分配,递归类型
Rc<T> 共享 单线程共享所有权
Arc<T> 共享 多线程共享所有权
Weak<T> 弱引用 与 Rc/Arc 相同 打破引用循环
Cell<T> 单一 内部可变性 (Copy 类型)
RefCell<T> 单一 内部可变性 (运行时检查)

决策流程图

需要堆分配吗?
├─ 是 → 单一所有者?
│        ├─ 是 → Box<T>
│        └─ 否 → 多线程?
│                ├─ 是 → Arc<T>
│                └─ 否 → Rc<T>
└─ 否 → 栈分配 (默认)

存在引用循环吗?
├─ 是 → 一个方向使用 Weak
└─ 否 → 常规 Rc/Arc

需要内部可变性吗?
├─ 是 → 需要线程安全吗?
│        ├─ 是 → Mutex<T> 或 RwLock<T>
│        └─ 否 → T: Copy? → Cell<T> : RefCell<T>
└─ 否 → 使用 &mut T

常见错误

问题 原因 修复方法
Rc 循环泄漏 相互强引用 一个方向使用 Weak
RefCell panic 运行时借用冲突 使用 try_borrow 或重构代码
Arc 开销 热点路径中的原子操作 如果是单线程,考虑使用 Rc
不必要的 Box 数据适合栈 移除 Box

反模式

反模式 为什么不好 更好的做法
到处用 Arc 不必要的原子操作开销 单线程时使用 Rc
到处用 RefCell 运行时 panic 设计清晰的所有权
对小类型用 Box 不必要的分配 栈分配
忽略 Weak 处理循环 内存泄漏 设计父子关系时使用 Weak

相关技能

何时 查看
所有权错误 m01-ownership
内部可变性详情 m03-mutability
多线程上下文 m07-concurrency
资源生命周期 m12-lifecycle