m02-resource by actionbook/rust-skills
npx skills add https://github.com/actionbook/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> | 单一 | 否 | 内部可变性(运行时检查) |
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 恐慌 | 运行时借用冲突 | 使用 try_borrow 或重构 |
| Arc 开销 | 热点路径中的原子操作 | 如果是单线程,考虑使用 Rc |
| 不必要的 Box | 数据适合放在栈上 | 移除 Box |
| 反模式 | 为什么不好 | 更好的做法 |
|---|---|---|
| 到处使用 Arc | 不必要的原子操作开销 | 单线程时使用 Rc |
| 到处使用 RefCell | 运行时恐慌 | 设计清晰的所有权 |
| 对小类型使用 Box | 不必要的分配 | 栈分配 |
| 对循环引用忽略 Weak | 内存泄漏 | 使用 Weak 设计父子关系 |
| 何时 | 参见 |
|---|---|
| 所有权错误 | m01-ownership |
| 内部可变性详情 | m03-mutability |
| 多线程上下文 | m07-concurrency |
| 资源生命周期 | m12-lifecycle |
每周安装次数
39
代码仓库
GitHub 星标数
809
首次出现
2026年1月23日
安全审计
安装于
gemini-cli36
codex35
opencode34
claude-code30
github-copilot30
cursor30
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
39
Repository
GitHub Stars
809
First Seen
Jan 23, 2026
Security Audits
Gen Agent Trust HubPassSocketPassSnykPass
Installed on
gemini-cli36
codex35
opencode34
claude-code30
github-copilot30
cursor30
Laravel架构模式指南:生产级开发模式与最佳实践
1,100 周安装
Cell<T>| Single |
| No |
| Interior mutability (Copy types) |
RefCell<T> | Single | No | Interior mutability (runtime check) |