Rust 智能指针实战:用 Rc 与 RefCell 处理单线程共享可变状态
test12026-10-084 次阅读
为什么需要 Rc<RefCell<T>>
借用检查器默认禁止同一份数据出现多个可变引用。在单线程里,我们确实想让多个持有者共享并修改同一份状态(比如事件总线、DOM 树节点),这时就用 Rc 做共享所有权、用 RefCell 把借用检查推迟到运行时。
1 一个最小事件总线
订阅者以闭包形式存进 Rc<RefCell<Vec<...>>>,订阅和发布都通过 clone 出来的 Rc 操作同一份集合。
use std::cell::RefCell;
use std::rc::Rc;
type Handler = Box<dyn Fn(&str)>;
struct EventBus {
handlers: Rc<RefCell<Vec<Handler>>>,
}
impl EventBus {
fn new() -> Self {
Self { handlers: Rc::new(RefCell::new(Vec::new())) }
}
fn subscribe(&self, h: Handler) {
self.handlers.borrow_mut().push(h);
}
fn emit(&self, msg: &str) {
for h in self.handlers.borrow().iter() {
h(msg);
}
}
}
2 父子共享同一份可变状态
把 Rc clone 给子节点,大家都能修改同一个计数器,且不需要把状态层层传参。
fn main() {
let bus = EventBus::new();
let b2 = bus.handlers.clone(); // 共享同一份 handlers
bus.subscribe(Box::new(|m| println!("收到: {}", m)));
bus.emit("hello");
// b2 与 bus 指向同一数据
println!("订阅数: {}", b2.borrow().len());
}
3 与 Arc<Mutex<T>> 的取舍
- 确定只在单线程内共享可变状态,用 Rc<RefCell<T>>,零原子开销,运行时借用失败会 panic。
- 需要跨线程共享,换成 Arc<Mutex<T>>(或 Arc<RwLock<T>>),把运行时借用检查升级为线程安全的互斥锁。
- 若数据其实不可变,只用 Rc<T> 即可,不必引入 RefCell 的可变开销。
T
test1
文章作者
为什么需要 Rc<RefCell<T>> 借用检查器默认禁止同一份数据出现多个可变引用。在单线程里,我们确实想让多个持...
- 分类
- 技术
- 发布时间
- 2026-10-08
- 字数
- 约 1271 字
- 阅读
- 4 次
