我觉得自己很傻,因为我已经多次浏览了Rust文档中的标记部分以及关于子类型和变异性的维基百科文章,但对生命周期子类型关系的理解并没有提高。
我想我只是习惯了“典型的面向对象编程风格”中的子类型关系,例如“Cat <: Animal”表示“Cat是Animal的一个子类型”,其中“S是T的子类型”意味着“任何S项都可以安全地用于期望T类型的上下文中”。到目前为止还好。
但是这如何适用于生命周期? Rust中现在定义的方式似乎是(*)
你可能会认为“当然是这个意思!”可能是因为<:看起来类似于小于运算符,也可能是因为“sub”让你想到子集,而短寿命肯定是长寿命的子集。但是如果'a不比'b长,'a真的是'b的子类型吗?让我们尝试应用维基百科对子类型关系的定义:(#1) 'a <: 'b <=> 生命周期a不超过生命周期b。
(#2) 'a <: 'b <=> 生命周期a可以安全地用于期望生命周期b的上下文中。
我的问题是我无法协调这一点。你如何从#2到#1?因为对我来说,这似乎是一个矛盾...如果你希望某些东西至少活到b,并且你有一个寿命为a且比b短的东西,显然不能在需要寿命为b的上下文中使用它,对吧?是我自己的问题还是我们对生命周期的子类型关系理解错了呢?
编辑:(*)根据IRC频道中的Ms2ger所说,情况确实如此。它也符合用于Items迭代器中的逆变寿命标记的文档。
编辑2:ContravariantLifetime和CovariantLifetime标记已被移除。现在我们有
PhantomData
作为marker模块的替代品。
a<:b
等价于b
的生命周期不长于a
的生命周期。 - mwhittakerp1
对应的区域比与p2
对应的区域存在时间更长,那么在我们期望使用*p2
类型的值时,使用*p1
类型的值是安全的。” - mwhittaker