水群学习法
云玩家,全靠群友水群时候蹭经验,群友太强啦!
关于Box<dyn Trait>
问题:
这里是box<struct> -> box<dyn trait>
, 还是box<struct -> dyn trait>
, 如果是后者,运行时怎么拿到size的?
|
|
答案 box<struct> -> box<dyn trait>
土豆:
Box<dyn Trait> == *mut dyn Trait == *mut T + *const metadata_of::<T as Trait>()
菜: 编译器会自动吧
box<T>
包装成box<T + metadate>
对吧土豆: 那是你亲手写的 as
菜: 其实
return box<T>
就是box<T> as box<dyn trait>
,这样对吧土豆: 照说是应该写出来
as _
的5大郎: Rust 能有限做 implicit conversion,因为 Rust implicit conversion 是非常少的,但是这里有
关于Variance
协变、逆变、不变 相关背景可以看这篇blog:Rust Subtyping and Variance
疯狂转发到我收藏夹
κόσμος: 假设你有一个
List<Dog>
,Dog 是 Animal 的子型,你肯定可以传进func(x: List<Animal>)
如果这个 func 里修改
List<Animal>
会发生什么?animals.clear(); animals.add(new Cat());
你会发现你的
List<Dog>
里出现了一个 Cat, 这就是为什么在 mutable 下不能 variant一样的办法,把这个函数想象成另一个函数的参数。一个函数需要一个
callback: fn(Dog)->Ret
,那理应是可以传一个fn(Animal)->Ret
作为这个 callback 的, 因为这个fn(Animal) -> Ret
一定可以处理 Dog 数据。所以fn(Animal)->Ret
<fn(Dog)->Ret
, 而 Dog < Animal,所以函数参数这样的一个型构造是逆变的
nicball: 你可以把
fn()→Cat
当成fn()→Animal
你可以把
fn(Animal)→()
当成fn(Cat)→()
所以函数对返回类型协变,对参数类型逆变
或者把他当成getter setter
可以想成读的时候协变,写的时候逆变
那可变的数据结构就只能不变了