Rust中RefCell的引用计数何时递减?
RefCell的引用计数何时递减?
RefCell的引用计数(不管是共享引用计数还是可变引用计数),会在对应的Ref或RefMut对象被销毁、离开当前作用域的时候自动递减。这是因为Ref和RefMut都实现了Drop trait,当它们的生命周期走到尽头时,Drop逻辑会自动帮我们更新RefCell内部的计数。
咱们结合你的两个例子来具体看:
可正常运行案例
use std::cell::RefCell; fn main() { let username = RefCell::new(""); *username.borrow_mut() = "Genese"; *username.borrow_mut() = "Salathiel"; println!("{}", username.borrow()); // Salathiel }
这里每次调用borrow_mut()都会生成一个临时的RefMut对象,这个对象只在当前赋值语句的生命周期内存在——当你完成*xxx = "Genese"这行操作后,这个临时的RefMut立刻就被销毁了,可变引用计数也随之减回0。所以第二次调用borrow_mut()时,RefCell的可变引用计数是0,完全符合“同一时间只能有一个可变引用”的规则,自然不会报错。
无法正常运行案例
use std::cell::RefCell; fn main() { let username = RefCell::new(""); let mut username_mutable_borrow = username.borrow_mut(); *username_mutable_borrow = "Genese"; let mut username_mutable_borrow = username.borrow_mut(); *username_mutable_borrow = "Salathiel"; println!("{}", username.borrow()); }
// thread 'main' panicked at 'already borrowed: BorrowMutError', src/main.rs:7:48
这里你把borrow_mut()返回的RefMut绑定到了变量username_mutable_borrow上,这个变量的作用域是从定义开始,一直到整个main函数结束(直到最后一行代码执行完毕后)。所以当你第二次调用borrow_mut()的时候,第一个RefMut还没有被销毁,RefCell的可变引用计数仍然是1,这时候就触发了运行时的借用检查错误——毕竟RefCell的核心规则和编译期借用规则是一致的:同一时间要么有多个共享引用,要么只能有一个可变引用,只是它把检查推迟到了运行时而已。
如果你想让这个案例正常运行,只需要手动限制第一个RefMut的作用域就行,比如用大括号包裹:
use std::cell::RefCell; fn main() { let username = RefCell::new(""); { let mut username_mutable_borrow = username.borrow_mut(); *username_mutable_borrow = "Genese"; } // 这里大括号结束,第一个RefMut被销毁,计数减回0 let mut username_mutable_borrow = username.borrow_mut(); *username_mutable_borrow = "Salathiel"; println!("{}", username.borrow()); // Salathiel }
内容的提问来源于stack exchange,提问作者Salathiel Genese
相关产品推荐
相关产品推荐

