Closed zjp-CN closed 2 months ago
#![feature(thin_box)] use std::boxed::ThinBox; use std::{mem::size_of, fmt::Debug, rc::Rc, sync::Arc}; type Pod = (usize, u32); fn main() { // 对于大部分指针,其大小可以是 8 或者 16 字节的(基于 64 位)。具体来说 // * 对于 T (隐式具有 Sized bound),那么很多指针的大小只是 8 字节 (thin) // * 尤其地,像 Rc/Arc 这样的智能指针,携带的元数据被放置于堆上,因此自身是 thin // * 对于 DST (trait objects/[T]/str),那么很多指针的大小是 16 字节 (fat) // * 尤其地,像裸指针和引用,在 DST 上是 fat dbg!( // 8 bytes size_of::<*const Pod>(), size_of::<&Pod>(), size_of::<Box<Pod>>(), size_of::<Rc<Pod>>(), size_of::<Arc<Pod>>(), // 16 bytes size_of::<*const dyn Debug>(), size_of::<&dyn Debug>(), size_of::<Box<dyn Debug>>(), size_of::<Rc<dyn Debug>>(), size_of::<Arc<dyn Debug>>(), ); // 当然,也有一些例外,ThinBox 始终为 8 字节,即使对于 DST dbg!( size_of::<ThinBox<Pod>>(), size_of::<ThinBox<dyn Debug>>(), ); // 以及还在设计中的 dyn-star 类型,见 niko 的博文,或者我的译文: // https://zjp-cn.github.io/translation/dyn-async-traits/2022-03-29-dyn-can-we-make-dyn-sized.html }
这里可能展开讲一下比较好,比如:哪些智能指针属于胖指针,哪些又和裸指针一样大(也许作为特例?)。因为这里想指出的是,有一部分智能指针确实属于胖指针。
对于大部分情况,指针类型 (引用、裸指针和智能指针)在 T: Sized 是 thin,在 T 为 DST 是 fat。
T: Sized
T
Pointee trait 的 Metadata 关联类型可以用来区分一个具体的指针类型是 thin 还是 fat:
Pointee
Metadata = ()
Metadata = usize
str/[T]
Metadata = DynMetadata<_>