为何在Rust中克隆Rc指针会增加strong_count?
关于Rust中Rc克隆行为的解释
先看你提供的代码:
use std::rc::Rc; fn rc_counter() -> Rc<String> { let p1 = Rc::new(String::from("Hello")); println!("count {}", Rc::strong_count(&p1)); // 1 // this is an owned type not a reference let p2 = p1.clone(); println!( "Count after the clone is created for the pointer {}", Rc::strong_count(&p1) ); // 2 p2 }
你疑惑的点在于:为什么Rc克隆后,p2和p1仍关联,没有复制堆上数据?
原因很简单:Rc<T>的clone()方法是专门设计的浅拷贝,只复制栈指针并增加引用计数,不会复制堆上的实际数据。
- 当你用
Rc::new创建p1时,堆上会生成一个String实例,Rc内部维护的强引用计数初始化为1,p1的栈指针指向这个堆数据。 - 调用
p1.clone()时,并不会复制堆上的String,而是在栈上生成另一个指向同一堆数据的指针p2,同时把Rc的强引用计数加1,所以此时计数变成2。
Rc的核心设计目的就是实现共享所有权,让多个变量可以共享同一份堆数据,通过引用计数来确保只有当所有所有者都被销毁时,堆数据才会被释放。如果每次克隆都深拷贝堆数据,那就违背了它的设计初衷。
如果确实需要完全独立的副本(深拷贝),你可以手动克隆内部的数据,再包裹成新的Rc:
let p2 = Rc::new(p1.as_str().to_string());
这样p2就会指向一个全新的堆上String,和p1的引用计数互不影响。
内容的提问来源于stack exchange,提问作者Yilmaz
相关产品推荐
相关产品推荐

