PhantomData<T>是一個(gè)零大小類型的標(biāo)記結(jié)構(gòu)體庆锦。
作用:
- 并不使用的類型辫继;
- 型變硼婿;
- 標(biāo)記擁有關(guān)系锌半;
- 自動(dòng)trait實(shí)現(xiàn)(send/sync);
并不使用的類型
生命周期
struct Slice<'a, T> {
start: *const T,
end: *const T,
}
然而寇漫,因?yàn)?a在結(jié)構(gòu)體中未使用刊殉,所以它是無界的。在結(jié)構(gòu)定義中禁止無限生命周期和類型州胳。
修改如下:
use std::marker;
struct Iter<'a, T: 'a> {
ptr: *const T,
end: *const T,
_marker: marker::PhantomData<&'a T>,
}
類型
pub struct RetryableSendCh<T, C: Sender<T>> {
ch: C,
name: &'static str,
marker: PhantomData<T>,
}
標(biāo)記擁有關(guān)系
struct Vec<T> {
data: *const T, // *const for variance!
len: usize,
cap: usize,
}
原生指針不具有所有權(quán)語義记焊,drop檢查器將認(rèn)為Vec<T>
不具有類型T的任何值。這將反過來使得它不需要擔(dān)心Vec在其析構(gòu)函數(shù)中丟棄任何T
栓撞。但是有可能T
被提前釋放遍膜。為了drop檢查器認(rèn)為vec一定擁有了T
的數(shù)據(jù)碗硬,修改如下:
use std::marker;
struct Vec<T> {
data: *const T, // *const for variance!
len: usize,
cap: usize,
_marker: marker::PhantomData<T>,
}
型變
- 不變
如果不能將一個(gè)類型替換為另一個(gè)類型,那么這個(gè)類型就稱之為:不變瓢颅。
- 逆變
可以由其基類替換恩尾。
- 協(xié)變
可以由其派生類型替換。
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 | - |
(*)如果逆變被廢除挽懦,這將是不變的翰意。