m02-resource
actionbook/rust-skills
Master Rust smart pointers and resource management for correct ownership patterns.
What is m02-resource?
This skill teaches when and how to use Box, Rc, Arc, Weak, Cell, and RefCell for heap allocation and shared ownership. Use it when you encounter ownership errors, need to choose between smart pointer types, or are designing resource lifecycles in single-threaded or multi-threaded contexts.
- Determine whether data needs single or shared ownership
- Choose the right smart pointer (Box, Rc, Arc, Weak) for your ownership model
- Identify and break reference cycles using Weak references
- Decide between interior mutability options (Cell vs RefCell) for runtime vs compile-time checks
- Trace ownership questions up to concurrency/design or down to implementation
How to install m02-resource
npx skills add https://github.com/actionbook/rust-skills --skill m02-resourceHow to use m02-resource
- 1.Identify your ownership need: single owner, shared immutable, or shared mutable
- 2.Check thread context: single-threaded or multi-threaded
- 3.Use the decision flowchart to select Box, Rc, Arc, or Weak
- 4.For shared mutable data, pair with Cell/RefCell (single-thread) or Mutex/RwLock (multi-thread)
- 5.If you have cycles, use Weak for one direction of the reference
Use cases
- Deciding between Rc and Arc based on thread context
- Fixing RefCell panics by restructuring ownership or using try_borrow
- Breaking circular reference leaks in parent-child data structures
- Choosing Box for recursive types or single-owner heap allocation
- Selecting Cell vs RefCell for interior mutability needs
- Rust developers learning ownership patterns
- Engineers designing multi-threaded systems
- Anyone debugging memory leaks or borrow checker errors
- Developers optimizing for performance (avoiding unnecessary Arc overhead)
m02-resource FAQ
Use Arc only if data is shared across threads; otherwise use Rc. Arc has atomic overhead that's unnecessary in single-threaded code.
Use try_borrow() instead of borrow() to handle conflicts gracefully, or restructure your code to avoid overlapping borrows.
Circular references (mutual strong references) cause leaks. Break the cycle by using Weak for one direction of the reference.
No. Box adds allocation overhead. Use stack allocation by default unless you need heap allocation for recursive types or trait objects.
Use Cell for Copy types with no runtime borrow checking. Use RefCell when you need runtime borrow checking for non-Copy types.
Full instructions (SKILL.md)
Source of truth, from actionbook/rust-skills.
name: m02-resource description: "CRITICAL: Use for smart pointers and resource management. Triggers: Box, Rc, Arc, Weak, RefCell, Cell, smart pointer, heap allocation, reference counting, RAII, Drop, should I use Box or Rc, when to use Arc vs Rc, 智能指针, 引用计数, 堆分配" user-invocable: false
Resource Management
Layer 1: Language Mechanics
Core Question
What ownership pattern does this resource need?
Before choosing a smart pointer, understand:
- Is ownership single or shared?
- Is access single-threaded or multi-threaded?
- Are there potential cycles?
Error → Design Question
| 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? |
Thinking Prompt
Before choosing a smart pointer:
-
What's the ownership model?
- Single owner → Box or owned value
- Shared ownership → Rc/Arc
- Weak reference → Weak
-
What's the thread context?
- Single-thread → Rc, Cell, RefCell
- Multi-thread → Arc, Mutex, RwLock
-
Are there cycles?
- Yes → One direction must be Weak
- No → Regular Rc/Arc is fine
Trace Up ↑
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? |
Trace Down ↓
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>>
Quick Reference
| 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 |
Cell<T> | Single | No | Interior mutability (Copy types) |
RefCell<T> | Single | No | Interior mutability (runtime check) |
Decision Flowchart
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
Common Errors
| 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-Patterns
| 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 |
Related Skills
| When | See |
|---|---|
| Ownership errors | m01-ownership |
| Interior mutability details | m03-mutability |
| Multi-thread context | m07-concurrency |
| Resource lifecycle | m12-lifecycle |
Related skills
More from actionbook/rust-skills and the wider catalog.

m03-mutability
Resolve Rust mutability conflicts by understanding ownership, borrowing rules, and interior mutability patterns.

m04-zero-cost
Master generics, traits, and zero-cost abstraction—choose static vs. dynamic dispatch correctly.

m05-type-driven
Use Rust's type system to make invalid states unrepresentable at compile time.

m06-error-handling
Master Rust error handling: when to use Result, Option, panic, and how to propagate errors effectively.

m07-concurrency
Master Rust concurrency: threads, async/await, channels, and thread-safe primitives.

m09-domain
Model domain concepts as Entities, Value Objects, and Aggregates using Rust ownership and type safety.