admin管理员组

文章数量:1202793

As is well known, contravariance is quite rare in Rust. According to the Rust Reference on variance, only fn(T) -> () is contravariant on T. I’ve never fully understood how the following conclusion is inferred:

Since &'static i32 <: &'a i32, it follows that fn(&'a i32) -> () <: fn(&'static i32) -> ().

Why is fn(&'a i32) a subtype of fn(&'static i32)? Can someone please provide a detailed derivation of this? Thank you very much!

From a logical deduction perspective, the conclusion I reached is that fn(&'static i32) is a subtype of fn(&'a i32). Clearly, this is incorrect. Here's my reasoning:

Since &'static i32 <: &'a i32, I concluded that in places where the return type is &'a i32, we could replace it with &'static i32. This is covariance, and such replacement follows the Liskov Substitution Principle (LSP).

For the types fn(&'a i32) and fn(&'static i32), I reasoned that wherever fn(&'a i32) is used, we can replace it with fn(&'static i32) because the Rust compiler will automatically downcast 'static to 'a. Thus, &'static i32 can naturally become &'a i32. This is also what we discussed before: &'static i32 is effectively a &'a i32.

According to this logic, it seems that fn(&'static i32) is the subtype and fn(&'a i32) is the supertype. So, we would conclude: if &'static i32 <: &'a i32, then fn(&'static i32) <: fn(&'a i32), which is not contravariance.

Though this conclusion is incorrect, I'm not sure where I misunderstood.

本文标签: rustRegarding the contravariance of fn(amp39a i32) gt ()Stack Overflow