Subtyping and Variance
子类型
T: U 的含义:
T是U的子类型 (subtype),或者说U是T的超类型 (supertype)- 任何需要使用
U的地方,都能够使用T1
1
可参考 Wiki 的英文描述:
If
Tis a subtype ofU, the subtyping relation is often writtenT <: U, to mean that any term of typeTcan be safely used in a context where a term of typeUis expected.
具体而言,对于生命周期这种泛型,'big: 'small 的含义:
'big是'small的子类型,任何需要使用'small的地方,都能够使用'big'big可当做'small去使用,因为'big所描述的代码区域 (region of code) 比'small更多'big包含'small,或者说'big的生命周期至少和'small一样长2- 换言之,我们可以忘记某物要存活
'big那么长,只需要记住某物需要存活'small那么长
2
英文表述为 'big outlives/lives at least as long as 'small
型变
Nomicon 一书这样描述和总结了 Rust 中的型变:
- 是一组子类型应该如何组织起来的规则
- 定义了禁用子类型的情况
- 是类型构造器相对于其参数所具有的属性
- 类型构造器
F的型变,就是指其输入的子类型如何影响其输出的子类型 - 在实际场景中,型变 (variance) 这一术语(很多情况下)指“协变” (covariance)
- 几乎所有对型变的考虑都是关于某事应该是协变的还是不变的
- 在 Rust 中见证逆变是相当困难的,尽管它实际上的确存在
类型构造器 (type constructor):
- 是任何不限制其参数 (unbound arguments) 的泛型类型
- 例如:
Vec是一个类型构造器,它接受类型T并返回Vec<T>&和&mut是接受两个输入的类型构造器:生命周期和被指向的类型
- 为了方便起见,通常将
F<T>称为类型构造器,这样我们就可以轻松地谈论T
| type constructor | variance | the subtyping of its outputs3 | memo |
|---|---|---|---|
F<T> | covariant | F<Sub>: F<Super> | subtyping "passes through" |
F<T> | contravariant | F<Super>: F<Sub> | subtyping is "inverted" |
F<T> | invariant | neither the two above | no subtyping relationship exists |
F<T, U> | covariant over T and covariant over U | F<SubT, SubU>: F<SuperT, SuperU> | F with a single field |
F<T, U> | covariant over T and contravariant over U | F<SubT, SuperU>: F<SuperT, SubU> | F with a single field |
F<T, U> | covariant over T and invariant over U | F<SubT, _>: F<SuperT, _> | F with a single field |
F<A> {..} | covariant over A | all uses of A are covariant | F with one or more fields |
F<A> {..} | contravariant over A | all uses of A are contravariant | F with one or more fields |
F<A> {..} | invariant over A | neither the two above | F with one or more fields |
3
given Sub: Super