[Advanced Rust] 1.12. Lifetimes (Advanced) Pt.2 - Lifetime Variance, Covariance, Invariance, Contravariance
1.12.1. Lifetime Variance Variance is a concept in Rust’s type system. It describes how generic parameters — especially lifetime parameters — relate to one another in the type hierarchy. We can think of it simply as variance describes which types are “subtypes” of other types , where “subtype” is somewhat similar to the concept used in Java and C#. In addition, variance also cares about when a “subtype” can replace a “supertype” and vice versa . In general, if A is a subtype of B, then A is at least as useful as B. Here is a Rust example: if a function takes &'a str , then &'static str can be passed in. Because 'static is a subtype of 'a , 'static lives at least as long as any 'a (and 'static can remain valid for the entire program). 1.12.2. Three Kinds of Lifetime Variance All types have variance. The variance associated with each type defines which similar types can be used in that type’s position. Note: the following content is fairly difficult. It is recommended that you first recall the ideas of sufficient conditions and necessary conditions from high school math. 1. Covariant Covariant means that a type can be replaced only by a “subtype.” Covariance means: if A <: B (A is a subtype of B), then F<A> <: F<B> (F<A> is also a subtype of F<B>) This is a transitive inheritance relationship from smaller to larger , similar to reasoning from a sufficient condition : if A holds, then B must also hold (A is a sufficient condition for B). For example, &'static T can replace &'a T , because &T is covariant over the lifetime 'a , so 'a can be replaced by one of its subtypes, such as 'static . 2. Invariant Invariant means that you must provide the exact specified type. Invariance means: A <: B cannot imply F<A> <: F<B>, and F<B> <: F<A> also cannot be inferred This means there is not enough relationship between F<A> and F<B> to derive one from the other, so they are neither sufficient conditions nor necessary conditions ; they are independent. For example, the mutable refe