Rc内部值被修改时的行为探究:代码输出差异解析
Rust中Rc引用计数变化与行为解析
一、count-1输出3的原因
初始时,a是一个Rc<List>实例,指向Cons(5, ...),此时它的强引用计数为1。
- 创建
b时,调用Rc::clone(&a),这会增加原Rc的强引用计数(而非深拷贝数据),计数变为2。 - 创建
c时,再次调用Rc::clone(&a),计数进一步变为3。
所以Rc::strong_count(&a)打印的是原Rc的引用数,结果为3。
二、count-2输出1的原因
代码中let d = &mut a; *d = Rc::new(Cons(1, Rc::new(Nil)));这一步,并不是修改原Rc内部的值(Rc<T>默认不允许修改内部数据,因为它是共享引用的载体),而是将a持有的Rc实例替换成了一个全新的Rc。
这个新的Rc仅被a自身持有,因此它的强引用计数为1,count-2打印的就是这个新实例的计数,结果为1。
三、b和c并未被丢弃,原Rc的行为说明
你提到的“b和c被丢弃”是误解:b和c作为main函数中的变量,依然处于作用域内,直到函数结束才会被销毁。
- 原
Rc(指向Cons(5, ...))的强引用计数,在a被替换后会从3降到2(因为a不再持有它,只剩b和c内部的Rc克隆引用)。 - 当
main函数执行完毕,b和c离开作用域时,它们内部的Rc克隆会被依次销毁,原Rc的计数会降到0,此时Rc才会自动释放它指向的List数据。
四、这种场景下Rc的核心行为
- 引用计数仅针对
Rc实例本身:Rc::clone只会增加计数,不复制底层数据;当持有Rc的变量被重新赋值或离开作用域时,对应Rc的计数会减少。 Rc<T>本身不可变:默认无法修改Rc指向的T数据,若需要可变共享,需配合RefCell<T>使用。- 计数归零自动销毁:当某个
Rc实例的强引用计数降到0时,它会自动释放底层的T数据,避免内存泄漏。
内容的提问来源于stack exchange,提问作者devj
相关产品推荐
相关产品推荐

