有人可以向我解释为什么Rc<>
不是Copy
?
我正在编写使用大量共享指针的代码,并且不得不一直输入.clone()
让我感到紧张。
在我看来,Rc<>
应该只包含一个固定大小的指针,因此类型本身应该是Sized
,因此Copy
,对吗?
我错过了什么吗?
答案 0 :(得分:28)
在我看来,
Rc<>
应该只包含一个固定大小的指针,因此类型本身应该是Sized
,因此Copy
,对吗?
这不是真的。 Rc
是 R 参考 C 的缩写。这意味着该类型会跟踪有多少引用指向拥有的数据。这样,一旦引用计数达到0,我们就可以同时拥有多个所有者并安全地释放数据。
但我们如何保持参考计数器有效且最新?确切地说,每当创建新的引用/所有者以及删除引用/所有者时,我们都必须执行某些操作。具体来说,我们必须在前一种情况下增加计数器,在后一种情况下减少计数器。
通过实现析构函数的Rust等效项documentation来减少计数器。只要变量超出范围,就会执行此drop()
函数 - 这完全符合我们的目标。
但我们什么时候做增量?你猜对了:clone()
。根据定义,Drop
表示只能通过复制位来复制类型:
只需复制位即可复制的类型(即
memcpy
)。
在我们的案例中并非如此,因为:是的,我们只是复制比特&#34;,但我们还做了额外的工作!我们确实需要增加参考计数器!
答案 1 :(得分:8)
如果类型实现Copy
(source),则无法实现Drop
。由于Rc
does implement it减少了引用计数,因此无法实现。
此外,Rc
不仅仅是一个指针。它由Shared
:
pub struct Rc<T: ?Sized> {
ptr: Shared<RcBox<T>>,
}
反过来,它不仅仅是一个指针:
pub struct Shared<T: ?Sized> {
pointer: NonZero<*const T>,
_marker: PhantomData<T>,
}
需要 PhantomData
来表达T
的所有权:
此标记对方差没有影响,但是必须具备 了解我们逻辑上拥有
T
。详情请见: https://github.com/rust-lang/rfcs/blob/master/text/0769-sound-generic-drop.md#phantom-data