关于 m02-resource
m02-resource 是面向 Rust 开发者的学习技能,帮助选择所有权和智能指针模式。它引导权衡独占或共享所有权、线程环境、引用环及分配需求。
主要功能
- 01所有权模式决策提示
- 02Box、Rc 和 Arc 使用指南
- 03按线程环境比较指针类型
- 04使用 Weak 处理引用环
- 05常见资源错误指南
适用场景
- 01为共享数据选择指针类型
- 02防止引用环导致内存泄漏
- 03判断是否需要堆分配
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ actionbook/ rust-skills --skill m02-resource安装后在 Claude Code 中输入/m02-resource确认已加载。
详细介绍
资源管理
第 1 层:语言机制
核心问题
此资源需要哪种所有权模式?
在选择智能指针之前,请先了解:
- 所有权是单一的还是共享的?
- 访问是单线程还是多线程的?
- 是否可能出现循环引用?
错误 → 设计问题
| 错误 | 不要只说 | 改为询问 |
|---|---|---|
| “需要堆分配” | “用 Box” | 为什么不能放在栈上? |
| Rc 内存泄漏 | “用 Weak” | 设计中是否必须有这个循环? |
| RefCell 引发 panic | “用 try_borrow” | 运行时检查是否是正确的做法? |
| 抱怨 Arc 开销 | “接受它” | 是否真的需要多线程访问? |
思考提示
在选择智能指针之前:
-
所有权模型是什么?
- 单一所有者 → Box 或自有值
- 共享所有权 → Rc/Arc
- 弱引用 → Weak
-
线程上下文是什么?
- 单线程 → Rc、Cell、RefCell
- 多线程 → Arc、Mutex、RwLock
-
是否存在循环引用?
- 是 → 其中一个方向必须使用 Weak
- 否 → 使用普通的 Rc/Arc 即可
向上追溯 ↑
指针选择不明确时,向上追溯到设计:
"Should I use Arc or Rc?"
↑ Ask: Is this data shared across threads?
↑ Check: m07-concurrency (thread model)
↑ Check: domain-* (performance constraints)
| 情况 | 追溯到 | 问题 |
|---|---|---|
| 混淆 Rc 与 Arc | m07-concurrency | 并发模型是什么? |
| RefCell 引发 panic | m03-mutability | 这里适合使用内部可变性吗? |
| 内存泄漏 | m12-lifecycle | 应该在哪里进行清理? |
向下追溯 ↓
从设计到实现:
"Need single-owner heap data"
↓ Use: Box<T>
"Need shared immutable data (single-thread)"
↓ Use: Rc<T>
"Need shared immutable data (multi-thread)"
↓ Use: Arc<T>
"Need to break reference cycle"
↓ Use: Weak<T>
"Need shared mutable data"
↓ Single-thread: Rc<RefCell<T>>
↓ Multi-thread: Arc<Mutex<T>> or Arc<RwLock<T>>
快速参考
| 类型 | 所有权 | 线程安全 | 使用场景 |
|---|---|---|---|
Box<T> | 单一 | 是 | 堆分配、递归类型 |
Rc<T> | 共享 | 否 | 单线程共享所有权 |
Arc<T> | 共享 | 是 | 多线程共享所有权 |
Weak<T> | 弱引用 | 与 Rc/Arc 相同 | 打破引用循环 |
Cell<T> | 单一 | 否 | 内部可变性(Copy 类型) |
RefCell<T> | 单一 | 否 | 内部可变性(运行时检查) |
决策流程图
Need heap allocation?
├─ Yes → Single owner?
│ ├─ Yes → Box<T>
│ └─ No → Multi-thread?
│ ├─ Yes → Arc<T>
│ └─ No → Rc<T>
└─ No → Stack allocation (default)
Have reference cycles?
├─ Yes → Use Weak for one direction
└─ No → Regular Rc/Arc
Need interior mutability?
├─ Yes → Thread-safe needed?
│ ├─ Yes → Mutex<T> or RwLock<T>
│ └─ No → T: Copy? → Cell<T> : RefCell<T>
└─ No → Use &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 |
评论
支持 Markdown