PhantomData<T>
是一个零大小类型的标记结构体。
作用:
- 并不使用的类型;
- 型变;
- 标记拥有关系;
- 自动trait实现(send/sync);
并不使用的类型
生命周期
1 | struct Slice<'a, T> { |
然而,因为’a在结构体中未使用,所以它是无界的。在结构定义中禁止无限生命周期和类型。
修改如下:
1 | use std::marker; |
类型
1 | pub struct RetryableSendCh<T, C: Sender<T>> { |
标记拥有关系
1 | struct Vec<T> { |
原生指针不具有所有权语义,drop检查器将认为Vec<T>
不具有类型T的任何值。这将反过来使得它不需要担心Vec在其析构函数中丢弃任何T
。但是有可能T
被提前释放。为了drop检查器认为vec一定拥有了T
的数据,修改如下:
1 | use std::marker; |
型变
- 不变
如果不能将一个类型替换为另一个类型,那么这个类型就称之为:不变。
- 逆变
可以由其基类替换。
- 协变
可以由其派生类型替换。
PhantomData
模式表
这是一张PhantomData
可以使用的所有方法的表格:
Phantom type | 'a |
T |
---|---|---|
PhantomData<T> |
- | variant (with drop check) |
PhantomData<&'a T> |
variant | variant |
PhantomData<&'a mut T> |
variant | invariant |
PhantomData<*const T> |
- | variant |
PhantomData<*mut T> |
- | invariant |
PhantomData<fn(T)> |
- | contravariant (*) |
PhantomData<fn() -> T> |
- | variant |
PhantomData<fn(T) -> T> |
- | invariant |
PhantomData<Cell<&'a ()>> |
invariant | - |
(*) 如果发生变性的冲突,这个是不变的。