0%
型变
- 型变(subtype)指根据原始类型子类型关系确定复杂类型子类型关系的规则。型变分为三种形式:
- 协变(covariant)。保持子类型关系
- 逆变(contravariant)。逆转子类型关系
- 不变(invariant)。不保持也不逆转类型关系,即无关
- Rust中只有生命周期有子类型关系,长类型是短类型的子类型
PhantomData<T>
是一个零大小类型的标记结构体,也叫幻影类型,它扮演三个角色:
- 型变
- 标记拥有关系(drop)
- 自动trait实现(Send和Sync)
几个重要的型变列表
- &’a T在
'a
和T
上是协变的,对应*const T
也是协变
- &’a mut T在
'a
上是协变,但在T
上是不变的
Fn(T)->U
在T
上是不变,在U
上是协变
Box<T>
、Vec<T>
以及其他集合对于它们包含的类型来说是协变
UnsafeCell<T>
、Cell<T>
、RefCell<T>
、Mutex<T>
以及其他内部可变类型在T
上都是不变,对应* mut T
也是不变
- 对于结构退来说,如果包含的字段都是协变,则结构体是协变,否则为不变。对
Phantomdata<T>
类型来说,有以下规则:
PhantomData<T>
,在T
上是协变
PhantomData<&'a T>
,在'a
和T
上是协变
PhantomData<&'a mut T>
,在'a
上是协变,在T
上是不变
PhantomData<*const T>
,在T
上是协变
PhantomData<*mut T>
,在T
上是不变
PhantomData<fn(T)>
,在T
上是逆变,如果以后修改语法,会成为不变
PhantomData<fn()->T>
,在T
上是协变
PhantomData<fn(T)->T>
,在T
上是不变
PhantomData<Cell<&'a()>>
,在'a
上是不变
- 当协变不会引起未定义行为的时候,可以用协变,否则就保证该类型为不变或逆变