rust_book_feedback icon indicating copy to clipboard operation
rust_book_feedback copied to clipboard

关于P210-P211中对协变, 逆变关系的描述

Open huangjj27 opened this issue 7 years ago • 2 comments

在参考了黑魔法书(nomicon)中subtyping小节的描述:

Some important variances (which we will explain in detail below): &'a T is covariant(协变) over 'a and T (as is *const T by metaphor) &'a mut T is covariant(协变) over 'a but invariant(不变) over T fn(T) -> U is contravariant(逆变) over T, but covariant(协变) over U Box, Vec, and all other collections are covariant(协变) over the types of their contents UnsafeCell<T>, Cell<T>, RefCell<T>, Mutex<T> and all other interior mutability types are invariant(不变) over T (as is *mut T by metaphor)

发现P210-P211中对协变, 逆变关系的描述有点小问题:

fn test_ret<'a>(f: fn() -> &'a str) {
     f();
}
fn main(){
     fn s() -> &'static str { return ""; }
    test_ret(s);
}

(P211) 上面这段代码可以编译通过. 这意味着fn() -> &'static str类型可以安全地转换为fn() -> &'a str. 那我们可以说, 类型fn(T)->U对于参数U具备逆变关系

我们知道, 书中在P210描述:

把一个生命周期更长的引用&'static str, 复制被了一个生命周期更短的引用 &'a str, 这是没有问题的.

这个描述在前文贴出的nomicon一书中得到了确认:

We have already covered why &'a T should be covariant over 'a when introducing subtyping: it's desirable to be able to pass longer-lived things where shorter-lived things are needed.

黑魔法书中表示, 因为生命周期的子类型关系是'long: 'short, 而&'long str转换成&'short str也是没有问题的, 故&'a T'a是协变(covariant)的. 如果用符号描述, 那应该是:

'long: 'short  => &'long str: &'short str

也就是: &'static str : &'a str. 这里借用rust语言中的约束符号(:)来表达左边是右边的子类型. 那么在函数返回值上:

&'static str : &'a str => (fn s() -> &'static str): (fn s() -> &'a str)

理应是协变, 而在函数参数位上:

&'static str : &'a str => fn s(&'a str) : fn s(&'static str)

理应是逆变.

huangjj27 avatar Sep 22 '18 12:09 huangjj27

嗯,说得对。这里“逆变”应该改为协变。参数位置上才是逆变。

F001 avatar Sep 23 '18 03:09 F001

这个不是笔误或者排版问题。是写的时候脑袋糊了。谢谢!

F001 avatar Sep 23 '18 03:09 F001