interior-mutability
内部可变性:UnsafeCell、Cell、RefCell
UnsafeCell:打破共享不可变的唯一合法方式
- 标准库内部(如
Cell/RefCell/Mutex/RwLock)都以UnsafeCell<T>包装以支持在&T下修改内部数据。
Cell 与 Copy 语义
Cell<T>提供按值 get/set 的内部可变性,要求T: Copy(或使用take/replace)。
use std::cell::Cell;
let x = Cell::new(1);
x.set(2);
assert_eq!(x.get(), 2);
RefCell 与运行时借用检查
RefCell<T>提供borrow()/borrow_mut(),在运行时强制“多读或独写”的借用规则,违规触发 panic。
use std::cell::RefCell;
let v = RefCell::new(vec![1]);
{
let mut r = v.borrow_mut();
r.push(2);
}
assert_eq!(v.borrow().len(), 2);
线程安全与并发版本
Cell/RefCell非线程安全,不是Sync;- 并发下使用
Mutex<T>、RwLock<T>、Atomic*或parking_lot替代; - 跨线程共享需配合
Arc<T>。
典型用法
- 面向对象样式的自引用/回调缓存 ;
- 惰性初始化(
OnceCell/Lazy); - 全局状态管理(
OnceLock+Arc)。
注意事项
RefCell借用计数的 panic 会 poison 容器(对Mutex而言),需考虑恢复策略;- 在 async 环境使用
Mutex时避免持锁.await,以防死锁或优先级反转。