1、每種型別都有一個資料對齊屬性。在X86平臺上u64和f64都是按照32位對齊的。
2、一種型別的大小是它對齊屬性的整數倍,這保證了這種型別的值在陣列中的偏移量都是其型別尺寸的整數倍,可以按照偏移量進行索引。需要注意的是,動態尺寸型別的大小和對齊可能無法靜態獲取。
3、結構體的對齊屬性等於它所有成員的對齊屬性中最大的那個。Rust會在必要的位置填充空白資料,以保證每一個成員都正確地對齊,同時整個型別的尺寸是對齊屬性的整數倍。
例子:
struct A {
a: u8,
b: u32,
c:u16,
}
會填充為:
struct A {
a: u8,
_pad1: [u8; 3], // 為了對齊b
b: u32,
c: u16,
_pad2: [u8; 2], // 保證整體型別尺寸是4的倍數
}
4、注意點,兩個同樣型別的複合型別其分佈規則並不一定一塵不變。例子:
struct A {
a: i32,
b: u64,
}
struct B {
a: i32,
b: u64,
}
Rust中不保證A的例項和B的例項有同樣的資料填充和成員順序。
原因:Rust編譯器會進行最佳化。如下:
struct Foo<T, U> {
count: u16,
data1: T,
data2: U,
}
對於上面的泛型結構體,Foo<u32, u16>和Foo<u16, u32>按照記憶體最佳化的原則要求兩者順序不一樣。
5、求解結構體的大小
使用std::mem,有兩種方法,分佈是size_of_val和size_of,例子如下:
use std::mem;
struct A {
a: u8,
b: u16,
}
fn main() {
let aa = A {a: 1, b:2};
println!("size = {}", mem::size_of_val(&aa));
println!("size = {}", mem::size_of::<A>());
println!("Hello, world!");
}
本作品採用《CC 協議》,轉載必須註明作者和本文連結