下面的 std 库 中 struct NodeRef 为什么用 PhantomData ?
pub struct NodeRef<BorrowType, K, V, Type> {
/// The number of levels that the node and the level of leaves are apart, a
/// constant of the node that cannot be entirely described by `Type`, and that
/// the node itself does not store. We only need to store the height of the root
/// node, and derive every other node's height from it.
/// Must be zero if `Type` is `Leaf` and non-zero if `Type` is `Internal`.
height: usize,
/// The pointer to the leaf or internal node. The definition of `InternalNode`
/// ensures that the pointer is valid either way.
node: NonNull<LeafNode<K, V>>,
_marker: PhantomData<(BorrowType, Type)>,
}
pub struct Immut<'a>(PhantomData<&'a ()>);
pub struct Mut<'a>(PhantomData<&'a mut ()>);
pub struct ValMut<'a>(PhantomData<&'a mut ()>);
pub enum Owned {}
pub enum Dying {}
pub enum Leaf {}
pub enum Internal {}
pub enum LeafOrInternal {}
impl<'a, K, V> NodeRef<marker::Mut<'a>, K, V, marker::LeafOrInternal>{...}
BorrowType 可以是 (Immut<'a>,Mut<'a>,Owned,Dying)其中之一。
Type 可以是 (Leaf,Internal,LeafOrInternal) 其中之一。
NodeRef 没有 impl Drop ,应该跟 dropck 没关系。
如果仅仅是防止出现unused type(lifetime) parameter,由于 两个 类型参数 对应的具体类型都是空的,不用 PhantomData 而真正使用(BorrowType, Type) ,是否一样?
1
共 9 条评论, 1 页
评论区
写评论嗯,也是zero。哪作用可能用在variance或其他auto traits上啦。
👇
leolee0101: 空enum 和 只有PhantomData的struct 是不是 zero-sized?
--
👇
Grainspring: 直接换成 (BorrowType, Type),就占用大小了呀。。。PhantomData<(BorrowType, Type)>是zero-sized.
--
👇
leolee0101: 这个我明白。注释是说 impl 的时候 根据类型参数的特化版本,实现不同的函数。不懂的地方是,struct NodeRef 声明里 PhantomData<(BorrowType, Type)> 直接换成 (BorrowType, Type) 是不是也是一样。这里的 PhantomData 有什么特别作用。
--
👇
Grobycn: 就在你贴出来的代码片段上面, 给出的文档就有说明:
空enum 和 只有PhantomData的struct 是不是 zero-sized?
--
👇
Grainspring: 直接换成 (BorrowType, Type),就占用大小了呀。。。PhantomData<(BorrowType, Type)>是zero-sized.
--
👇
leolee0101: 这个我明白。注释是说 impl 的时候 根据类型参数的特化版本,实现不同的函数。不懂的地方是,struct NodeRef 声明里 PhantomData<(BorrowType, Type)> 直接换成 (BorrowType, Type) 是不是也是一样。这里的 PhantomData 有什么特别作用。
--
👇
Grobycn: 就在你贴出来的代码片段上面, 给出的文档就有说明:
直接换成 (BorrowType, Type),就占用大小了呀。。。PhantomData<(BorrowType, Type)>是zero-sized.
--
👇
leolee0101: 这个我明白。注释是说 impl 的时候 根据类型参数的特化版本,实现不同的函数。不懂的地方是,struct NodeRef 声明里 PhantomData<(BorrowType, Type)> 直接换成 (BorrowType, Type) 是不是也是一样。这里的 PhantomData 有什么特别作用。
--
👇
Grobycn: 就在你贴出来的代码片段上面, 给出的文档就有说明:
这个我明白。注释是说 impl 的时候 根据类型参数的特化版本,实现不同的函数。不懂的地方是,struct NodeRef 声明里 PhantomData<(BorrowType, Type)> 直接换成 (BorrowType, Type) 是不是也是一样。这里的 PhantomData 有什么特别作用。
--
👇
Grobycn: 就在你贴出来的代码片段上面, 给出的文档就有说明:
https://doc.rust-lang.org/stable/reference/special-types-and-traits.html?highlight=PhantomData#phantomdata
phantomdata that is considered to own a T for the purposes of variance, drop check, and auto traits.
它会拥有T的variance、drop check、autotraits的特性。。比如:若T:!Send,则phantomdata:!send
就在你贴出来的代码片段上面, 给出的文档就有说明:
意思是说 NodeRef 结构声明中,直接去掉 PhantomData 。
--
👇
Neutron3529: 你准备怎么直接使用BorrowType?
不定义到结构体里面你根本用不了。
你准备怎么直接使用BorrowType?
不定义到结构体里面你根本用不了。
我觉得是一样的, 使用PhantomData可能更多的是从可读性角度考虑的