为什么 std::rc::Rc<> 不是复制?
Why is std::rc::Rc<> not Copy?
谁能给我解释一下为什么 Rc<>
不是 Copy
?
我正在编写使用大量共享指针的代码,不得不一直键入 .clone()
让我很紧张。
在我看来 Rc<>
应该只包含一个固定大小的指针,所以类型本身应该是 Sized
,因此 Copy
,对吗?
我是不是漏掉了什么?
It seems to me that Rc<>
should just consist of a pointer, which is a fixed size, so the type itself should be Sized
and hence Copy
, right?
这不完全正确。 Rc
是 Rreference Counted 的缩写。这意味着该类型会跟踪有多少引用指向拥有的数据。这样我们就可以同时拥有多个所有者并在引用计数达到 0 时安全地释放数据。
但是我们如何使参考计数器保持有效和最新?确切地说,每当创建新的 reference/owner 和删除 reference/owner 时,我们都必须做一些事情。具体来说,我们必须在前一种情况下增加计数器,在后者中减少计数器。
通过实现 Drop
来减少计数器,Rust 相当于析构函数。只要变量超出范围,就会执行此 drop()
函数 - 非常适合我们的目标。
但是我们什么时候做增量?您猜对了:在 clone()
中。 The Copy
trait,根据定义,表示一个类型可以通过复制位来复制:
Types that can be copied by simply copying bits (i.e. memcpy
).
在我们的案例中这不是真的,因为:是的,我们 "just copy bits",但我们还做了额外的工作!我们确实需要增加我们的参考计数器!
如果一个类型实现了 Drop
(source). Since 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
的所有权:
this marker has no consequences for variance, but is necessary for
dropck to understand that we logically own a T
.
For details, see:
https://github.com/rust-lang/rfcs/blob/master/text/0769-sound-generic-drop.md#phantom-data
谁能给我解释一下为什么 Rc<>
不是 Copy
?
我正在编写使用大量共享指针的代码,不得不一直键入 .clone()
让我很紧张。
在我看来 Rc<>
应该只包含一个固定大小的指针,所以类型本身应该是 Sized
,因此 Copy
,对吗?
我是不是漏掉了什么?
It seems to me that
Rc<>
should just consist of a pointer, which is a fixed size, so the type itself should beSized
and henceCopy
, right?
这不完全正确。 Rc
是 Rreference Counted 的缩写。这意味着该类型会跟踪有多少引用指向拥有的数据。这样我们就可以同时拥有多个所有者并在引用计数达到 0 时安全地释放数据。
但是我们如何使参考计数器保持有效和最新?确切地说,每当创建新的 reference/owner 和删除 reference/owner 时,我们都必须做一些事情。具体来说,我们必须在前一种情况下增加计数器,在后者中减少计数器。
通过实现 Drop
来减少计数器,Rust 相当于析构函数。只要变量超出范围,就会执行此 drop()
函数 - 非常适合我们的目标。
但是我们什么时候做增量?您猜对了:在 clone()
中。 The Copy
trait,根据定义,表示一个类型可以通过复制位来复制:
Types that can be copied by simply copying bits (i.e.
memcpy
).
在我们的案例中这不是真的,因为:是的,我们 "just copy bits",但我们还做了额外的工作!我们确实需要增加我们的参考计数器!
如果一个类型实现了 Drop
(source). Since 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
的所有权:
this marker has no consequences for variance, but is necessary for dropck to understand that we logically own a
T
.For details, see: https://github.com/rust-lang/rfcs/blob/master/text/0769-sound-generic-drop.md#phantom-data