m02-resource by zhanghandong/rust-skills
npx skills add https://github.com/zhanghandong/rust-skills --skill m02-resource第一层:语言机制
此资源需要何种所有权模式?
在选择智能指针之前,需要理解:
| 错误 | 不要只是说 | 应该问 |
|---|---|---|
| "需要堆分配" | "用 Box" | 为什么不能放在栈上? |
| Rc 内存泄漏 | "用 Weak" | 设计上真的需要循环引用吗? |
| RefCell 恐慌 | "用 try_borrow" | 运行时检查是正确的方法吗? |
| 抱怨 Arc 开销 | "接受它" | 真的需要多线程访问吗? |
在选择智能指针之前:
广告位招租
在这里展示您的产品或服务
触达数万 AI 开发者,精准高效
当指针选择不明确时,追溯到设计层面:
"我应该用 Arc 还是 Rc?"
↑ 问:这个数据是否在线程间共享?
↑ 检查:m07-concurrency (线程模型)
↑ 检查:domain-* (性能约束)
| 情况 | 追溯至 | 问题 |
|---|---|---|
| 混淆 Rc 和 Arc | m07-concurrency | 并发模型是什么? |
| RefCell 恐慌 | 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 恐慌 | 运行时借用冲突 | 使用 try_borrow 或重构 |
| Arc 开销 | 热点路径上的原子操作 | 如果是单线程,考虑使用 Rc |
| 不必要的 Box | 数据可以放在栈上 | 移除 Box |
| 反模式 | 为何不好 | 更好的做法 |
|---|---|---|
| 到处用 Arc | 不必要的原子操作开销 | 单线程场景使用 Rc |
| 到处用 RefCell | 运行时恐慌 | 设计清晰的所有权 |
| 对小类型用 Box | 不必要的分配 | 栈分配 |
| 对循环引用忽略 Weak | 内存泄漏 | 使用 Weak 设计父子关系 |
| 何时查看 | 参见 |
|---|---|
| 所有权错误 | m01-ownership |
| 内部可变性详情 | m03-mutability |
| 多线程上下文 | m07-concurrency |
| 资源生命周期 | m12-lifecycle |
每周安装量
626
代码仓库
GitHub 星标数
912
首次出现
2026年1月20日
安全审计
安装于
opencode573
codex557
gemini-cli546
github-copilot533
amp485
kimi-cli480
Layer 1: Language Mechanics
What ownership pattern does this resource need?
Before choosing a smart pointer, understand:
| Error | Don't Just Say | Ask Instead |
|---|---|---|
| "Need heap allocation" | "Use Box" | Why can't this be on stack? |
| Rc memory leak | "Use Weak" | Is the cycle necessary in design? |
| RefCell panic | "Use try_borrow" | Is runtime check the right approach? |
| Arc overhead complaint | "Accept it" | Is multi-thread access actually needed? |
Before choosing a smart pointer:
What's the ownership model?
What's the thread context?
Are there cycles?
When pointer choice is unclear, trace to design:
"Should I use Arc or Rc?"
↑ Ask: Is this data shared across threads?
↑ Check: m07-concurrency (thread model)
↑ Check: domain-* (performance constraints)
| Situation | Trace To | Question |
|---|---|---|
| Rc vs Arc confusion | m07-concurrency | What's the concurrency model? |
| RefCell panics | m03-mutability | Is interior mutability right here? |
| Memory leaks | m12-lifecycle | Where should cleanup happen? |
From design to implementation:
"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>>
| Type | Ownership | Thread-Safe | Use When |
|---|---|---|---|
Box<T> | Single | Yes | Heap allocation, recursive types |
Rc<T> | Shared | No | Single-thread shared ownership |
Arc<T> | Shared | Yes | Multi-thread shared ownership |
Weak<T> | Weak ref | Same as Rc/Arc | Break reference cycles |
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
| Problem | Cause | Fix |
|---|---|---|
| Rc cycle leak | Mutual strong refs | Use Weak for one direction |
| RefCell panic | Borrow conflict at runtime | Use try_borrow or restructure |
| Arc overhead | Atomic ops in hot path | Consider Rc if single-threaded |
| Box unnecessary | Data fits on stack | Remove Box |
| Anti-Pattern | Why Bad | Better |
|---|---|---|
| Arc everywhere | Unnecessary atomic overhead | Use Rc for single-thread |
| RefCell everywhere | Runtime panics | Design clear ownership |
| Box for small types | Unnecessary allocation | Stack allocation |
| Ignore Weak for cycles | Memory leaks | Design parent-child with Weak |
| When | See |
|---|---|
| Ownership errors | m01-ownership |
| Interior mutability details | m03-mutability |
| Multi-thread context | m07-concurrency |
| Resource lifecycle | m12-lifecycle |
Weekly Installs
626
Repository
GitHub Stars
912
First Seen
Jan 20, 2026
Security Audits
Gen Agent Trust HubPassSocketPassSnykPass
Installed on
opencode573
codex557
gemini-cli546
github-copilot533
amp485
kimi-cli480
React 组合模式指南:Vercel 组件架构最佳实践,提升代码可维护性
103,800 周安装
Cell<T>| Single |
| No |
| Interior mutability (Copy types) |
RefCell<T> | Single | No | Interior mutability (runtime check) |