| name | rust-resource |
| description | 智能指针与资源管理专家。处理 Box, Rc, Arc, Weak, RefCell, Cell, interior mutability, RAII, Drop, 堆分配, 引用计数, 智能指针--- |
选择决策树
需要共享数据吗?
│
├─ 否 → 单 owner
│ ├─ 需要堆分配? → Box<T>
│ └─ 栈上即可? → 直接值类型
│
└─ 是 → 需要共享
│
├─ 单线程?
│ ├─ 可变? → Rc<RefCell<T>>
│ └─ 只读? → Rc<T>
│
└─ 多线程?
├─ 可变? → Arc<Mutex<T>> 或 Arc<RwLock<T>>
└─ 只读? → Arc<T>
智能指针对比
| 类型 | 所有权 | 线程安全 | 适用场景 |
|---|
Box<T> | 单 owner | Yes | 堆分配、递归类型、trait object |
Rc<T> | 共享 | No | 单线程共享、避免 clone |
Arc<T> | 共享 | Yes | 多线程共享、只读数据 |
Weak<T> | 弱引用 | - | 打破循环引用 |
RefCell<T> | 单 owner | No | 运行时借用检查 |
Cell<T> | 单 owner | No | Copy 类型的内部可变性 |
常见错误与解决方案
Rc 循环引用泄漏
struct Node {
value: i32,
next: Option<Rc<Node>>,
}
struct Node {
value: i32,
next: Option<Weak<Node>>,
}
RefCell panic
let cell = RefCell::new(vec![1, 2, 3]);
let mut_borrow = cell.borrow_mut();
let another_borrow = cell.borrow();
if let Ok(mut_borrow) = cell.try_borrow_mut() {
}
Arc 开销投诉
let shared = Arc::new(data);
let shared = Rc::new(data);
内部可变性选择
struct Counter {
count: Cell<u32>,
}
struct Container {
items: RefCell<Vec<Item>>,
}
struct SharedContainer {
items: Mutex<Vec<Item>>,
}
RAII 与 Drop
struct File {
handle: std::fs::File,
}
impl Drop for File {
fn drop(&mut self) {
println!("File closed");
}
}
struct Guard<'a> {
resource: &'a Resource,
}
impl Drop for Guard<'_> {
fn drop(&mut self) {
self.resource.release();
}
}
性能提示
| 场景 | 建议 |
|---|
| 大量小对象 | Rc::make_mut() 避免 clone |
| 频繁读取 | RwLock 比 Mutex 更好 |
| 计数器 | 用 AtomicU64 而非 Mutex<u64> |
| 缓存 | 考虑 moka 或 cached crate |
何时不用智能指针
- 栈上数据足够 → 用值类型
- 借用即可满足 → 用引用
&T
- 生命周期简单 → 不要过度抽象