You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.29 00:17:28