“trait object 是胖指针”这句话到底指什么?这篇把胖指针拆开,看地址与元数据,再验证 vtable 与类型的对应关系、上转型、指针比较、size_of_val、Drop 和 Any 向下转型都是怎么靠 vtable 实现的。
编译:成功
运行(退出码 0):
&u8 8 &[u8] 16 &str 16 &dyn Debug 16 *const dyn Debug 16 Box<dyn Debug> 16
&v[1..4] 拆开:数据地址 = v 的地址 + 1: true 长度元数据 = 3
&str 的元数据是字节数,不是字符数:"héllo" 长度 6 字节(5 个字符)
&dyn Debug 转成 *const (): 8 字节数据地址 = 0x10236b3c0,vtable 信息丢掉了trait object 与动态分发的基础见Trait Object 与动态分发(那篇里已经读过 vtable 的布局)。
编译:成功
运行(退出码 0):
两个 A:vtable 相同 true A 与 B:vtable 相同 false 数据地址不同 true
上转型 &dyn Sub → &dyn Super:数据地址不变 true vtable 指针变了 false(这个例子里没变) 通过 Super 调用 name() = A 编译:成功
运行(退出码 0):
同一个对象两个 &dyn T:ptr::eq(a, b) = true
按数据地址比较(转成 *const ()):true 编译:成功
运行(退出码 0):
cat size_of_val = 0 align_of_val = 1
elephant size_of_val = 100 align_of_val = 1
tiger size_of_val = 16 align_of_val = 8
Vec<Box<dyn Animal>> 离开作用域:
Noisy(tiger) 的 Drop 通过 vtable 被调用 编译:成功
运行(退出码 0):
i32 = 5
&str = str
String = owned
未知类型,type_id 与 f64 相同吗: true切片的胖指针见Slice 的胖指针。