考虑:
fn main() {
// Prints 8, 8, 16
println!(
"{}, {}, {}",
std::mem::size_of::<Box<i8>>(),
std::mem::size_of::<Box<&[i8]>>(),
std::mem::size_of::<Box<[i8]>>(),
);
}
为什么拥有的片需要16个字节,但引用的片只需要8个?
Box<T>
基本上是*const T
(实际上它是围绕Unique<T>
的新型,它本身是NonNull<T>
与PhantomData<T>
(对于dropck),但为了简单起见,我们坚持使用*const T
)。
Rust中的指针通常与size_of::<usize>()
具有相同的大小,除非T
是dynamically sized type(DST)。目前,Box<DST>
的大小是2 * size_of::<usize>()
(在撰写本文时,确切的表示形式并不稳定)。指向DST的指针称为FatPtr
。
目前,有两种DST:切片和特征。切片的FatPtr
定义如下:
#[repr(C)]
struct FatPtr<T> {
data: *const T,
len: usize,
}
注意:对于特征指针,len
被指向vtable
的指针替换。
有了这些信息,您的问题就可以得到解答:
Box<i8>
:i8
是一个大小类型=>基本上与*const i8
相同=> 8字节大小(64位指针宽度)Box<[i8]>
:[i8]
是DST =>与FatPtr<i8>
基本相同=> 16字节大小(64位指针宽度)Box<&[i8]>
:&[i8]
不是夏令时。它与*const FatPtr<i8>
=> 8字节大小基本相同(64位指针宽度)引用的大小取决于引用类型的“大小”:
#[repr(C)]
struct FatPtr<T> {
data: *const T,
len: usize,
}
Box
是一种指向堆的特殊指针,但它仍然是一个指针。
知道了,你理解:
Box<i8>
是8个字节,因为i8
的大小,Box<&[i8]>
是8个字节,因为参考大小,Box<[i8]>
是16个字节,因为切片是未分级的。