Function std::mem::size_of

1.0.0 (const: 1.24.0) · source ·
pub const fn size_of<T>() -> usize
Expand description

返回类型的大小 (以字节为单位)。

更具体地说,这是具有该项类型 (包括对齐填充) 的数组中连续元素之间的字节偏移量。

因此,对于任何类型的 T 和长度 n[T; n] 的大小都是 n * size_of::<T>()

一般来说,一个类型的大小在不同的编译中是不稳定的,但是特定的类型,比如原语,是稳定的。

下表提供了原语的大小。

Typesize_of::<Type>()
()0 bool

此外,usizeisize 具有相同的大小。

*const T&TBox<T>Option<&T>Option<Box<T>> 类型都具有相同的大小。 如果 TSized,则所有这些类型的大小都与 usize 相同。

指针的可变性不会改变其大小。这样,&T&mut T 具有相同的大小。 对于 *const T*mut T 同样。

#[repr(C)] 项的大小

项的 C 表示具有已定义的布局。 使用此布局,只要所有字段的大小都稳定,则项的大小也将保持稳定。

结构体的大小

对于 struct,大小由以下算法确定。

对于结构体中按声明顺序排序的每个字段:

  1. 添加字段的大小。
  2. 将当前大小四舍五入到下一个字段的 对齐 的最接近倍数。

最后,将结构体的大小四舍五入到其 对齐 的最接近倍数。 结构体的排列通常是其所有字段中最大的排列; 这可以通过使用 repr(align(N)) 进行更改。

C 不同,零大小的结构体不会四舍五入为一个字节。

枚举的大小

除判别式外不包含任何数据的枚举的大小与为其编译的平台上的 C 枚举的大小相同。

union 的大小

union 的大小是其最大字段的大小。

C 不同,零大小的 union 不会被四舍五入到一个字节的大小。

Examples

use std::mem;

// 一些原语
assert_eq!(4, mem::size_of::<i32>());
assert_eq!(8, mem::size_of::<f64>());
assert_eq!(0, mem::size_of::<()>());

// 一些数组
assert_eq!(8, mem::size_of::<[i32; 2]>());
assert_eq!(12, mem::size_of::<[i32; 3]>());
assert_eq!(0, mem::size_of::<[i32; 0]>());


// 指针大小相等
assert_eq!(mem::size_of::<&i32>(), mem::size_of::<*const i32>());
assert_eq!(mem::size_of::<&i32>(), mem::size_of::<Box<i32>>());
assert_eq!(mem::size_of::<&i32>(), mem::size_of::<Option<&i32>>());
assert_eq!(mem::size_of::<Box<i32>>(), mem::size_of::<Option<Box<i32>>>());
Run

使用 #[repr(C)]

use std::mem;

#[repr(C)]
struct FieldStruct {
    first: u8,
    second: u16,
    third: u8
}

// 第一个字段的大小为 1,因此请在大小上加 1。大小是 1.
// 第二个字段的对齐方式为 2,因此在填充大小上加 1。大小是 2.
// 第二个字段的大小为 2,因此将大小加 2。大小是 4.
// 第三个字段的对齐方式为 1,因此请在填充大小上加上 0。大小是 4.
// 第三个字段的大小为 1,因此请在大小上加 1。大小是 5.
// 最后,结构体的对齐方式为 2 (因为其字段之间的最大对齐方式为 2),所以在填充的大小上加 1。
// 大小是 6.
assert_eq!(6, mem::size_of::<FieldStruct>());

#[repr(C)]
struct TupleStruct(u8, u16, u8);

// 元组结构体遵循相同的规则。
assert_eq!(6, mem::size_of::<TupleStruct>());

// 请注意,对字段重新排序可以减小大小。
// 我们可以通过将 `third` 放在 `second` 之前删除两个填充字节。
#[repr(C)]
struct FieldStructOptimized {
    first: u8,
    third: u8,
    second: u16
}

assert_eq!(4, mem::size_of::<FieldStructOptimized>());

// union 的大小是最大字段的大小。
#[repr(C)]
union ExampleUnion {
    smaller: u8,
    larger: u16
}

assert_eq!(2, mem::size_of::<ExampleUnion>());
Run