SuperAPI AI Directory

rust-resource

Coding & development

View repository

Updated 10-15 21:39

About this skill

Choose a decision tree

需要共享数据吗?
    │
    ├─ 否 → 单 owner
    │   ├─ 需要堆分配? → Box<T>
    │   └─ 栈上即可? → 直接值类型
    │
    └─ 是 → 需要共享
          │
          ├─ 单线程?
          │   ├─ 可变? → Rc<RefCell<T>>
          │   └─ 只读? → Rc<T>
          │
          └─ 多线程?
                ├─ 可变? → Arc<Mutex<T>> 或 Arc<RwLock<T>>
                └─ 只读? → Arc<T>

Smart pointer comparison

Type Ownership Thread safety Use case
Box<T> Single owner Yes Heap allocation, recursive types, trait object
Rc<T> Shared No Single-threaded sharing, avoid clone
Arc<T> Shared Yes Multi-threaded sharing, read-only data
Weak<T> Weak reference - Break reference cycles
RefCell<T> Single owner No Runtime borrow checking
Cell<T> Single owner No Interior mutability for Copy types

Common errors and solutions

Rc reference cycle leak

// ❌ 内存泄漏:两个 Rc 互相引用
struct Node {
    value: i32,
    next: Option<Rc<Node>>,
}

// ✅ 解决方案:使用 Weak 打破循环
struct Node {
    value: i32,
    next: Option<Weak<Node>>,
}

RefCell panic

// ❌ 运行时 panic:双重可变借用
let cell = RefCell::new(vec![1, 2, 3]);
let mut_borrow = cell.borrow_mut();
let another_borrow = cell.borrow(); // panic!

// ✅ 解决方案:使用 try_borrow
if let Ok(mut_borrow) = cell.try_borrow_mut() {
    // 安全使用
}

Arc overhead complaints

// ❌ 不必要的 Arc:单线程环境
let shared = Arc::new(data);

// ✅ 单线程用 Rc
let shared = Rc::new(data);

// ❌ 多线程不必要的原子操作
// 如果确定不需要跨线程共享,就不要用 Arc

Choosing interior mutability

// T 是 Copy 类型 → Cell
struct Counter {
    count: Cell<u32>,
}

// T 不是 Copy → RefCell
struct Container {
    items: RefCell<Vec<Item>>,
}

// 多线程 → Mutex 或 RwLock
struct SharedContainer {
    items: Mutex<Vec<Item>>,
}

RAII and Drop

struct File {
    handle: std::fs::File,
}

impl Drop for File {
    fn drop(&mut self) {
        // 自动释放资源
        println!("File closed");
    }
}

// 使用 guard pattern 确保清理
struct Guard<'a> {
    resource: &'a Resource,
}

impl Drop for Guard<'_> {
    fn drop(&mut self) {
        self.resource.release();
    }
}

Performance tips

Scenario Recommendation
Many small objects Rc::make_mut() Avoid clone
Frequent reads RwLock is better than Mutex is better
Counter Use AtomicU64 instead of Mutex<u64>
Cache Consider moka or cached crate

When not to use smart pointers

  • Stack data is sufficient → use value types
  • Borrowing suffices → use references &T
  • Simple lifetimes → don't over-abstract