考虑:
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]>>(),
);
}
Run Code Online (Sandbox Code Playgroud)
为什么拥有的切片占用16个字节,而引用的切片仅占用8个字节?
Tim*_*ann 17
Box<T>基本上是*const T(实际上,它是围绕的新类型Unique<T>,它本身是NonNull<T>with PhantomData<T>(用于dropck的),但是*const T为了简单起见,请坚持使用)。
鲁斯特指针通常具有相同的尺寸size_of::<usize>(),除了当T为动态大小的类型(DST)。目前,一个Box<DST>是2 * size_of::<usize>()大小(确切的表示并不稳定,在写作的时候)。指向DST的指针称为FatPtr。
当前,有两种DST:切片和特征。FatPtr切片的A 定义如下:
#[repr(C)]
struct FatPtr<T> {
data: *const T,
len: usize,
}
Run Code Online (Sandbox Code Playgroud)
注意:对于特征指针,len由代替vtable。
利用这些信息,可以回答您的问题:
Box<i8>:i8是一个大小类型=>基本上与*const i8=> 8个字节相同(具有64位指针宽度)Box<[i8]>:[i8]是DST =>基本上等于FatPtr<i8>=> 16字节大小(具有64位指针宽度)Box<&[i8]>:&[i8]是不是一个DST。它基本上与*const FatPtr<i8>=> 8字节大小相同(具有64位指针宽度)引用的大小取决于引用类型的“大小”:
对无大小类型的引用是指向内存和所指向数据大小的指针。这就是所谓的胖指针:
#[repr(C)]
struct FatPtr<T> {
data: *const T,
len: usize,
}
Run Code Online (Sandbox Code Playgroud)ABox是一种特殊的指向堆的指针,但它仍然是一个指针。
知道了这一点,你就明白了:
Box<i8>是 8 个字节,因为i8大小,Box<&[i8]> 是 8 个字节,因为引用的大小,Box<[i8]> 是 16 字节,因为切片未确定大小。