Go では、構造体フィールドが宣言される順序が構造体のサイズに影響を与える可能性があります。なぜですか?
type A struct { a bool b int64 c int } type B struct { b int64 a bool c int }
これらの構造体のサイズを出力すると、次のことがわかります:
fmt.Println(unsafe.Sizeof(A{})) // Output: 24 fmt.Println(unsafe.Sizeof(B{})) // Output: 16
同じフィールドがあるにもかかわらず、サイズが異なります。
フィールドが配置されているかどうか特定のメモリ アドレスから開始するかどうかは、ターゲット アーキテクチャによって異なります。たとえば、int64 では 8 バイトのアライメントが必要です。 A では、最初のフィールドは bool、つまり 1 バイトです。 b (int64) を正しく位置合わせするには、a の後に 7 バイトの暗黙的なパディングがあります。
B では、a の後に int (4 バイト) が続くため、パディングは 3 バイトのみ必要です。これはサイズの違いを説明しています。
// Offset (in bytes) for struct A fmt.Println(unsafe.Offsetof(a.a)) // Output: 0 fmt.Println(unsafe.Offsetof(a.b)) // Output: 8 fmt.Println(unsafe.Offsetof(a.c)) // Output: 16 // Offset for struct B fmt.Println(unsafe.Offsetof(b.b)) // Output: 0 fmt.Println(unsafe.Offsetof(b.a)) // Output: 8 fmt.Println(unsafe.Offsetof(b.c)) // Output: 12
type C struct {}
サイズがゼロの構造体のサイズはゼロであり、メモリ割り当てがないことを示します。サイズ 0 の構造体を参照する別個の変数にもかかわらず、同じメモリ アドレスを共有する可能性があります:
a := C{} b := C{} c := [0]int{} d := [3]C{} fmt.Printf("%p %p %p %p %p", &a, &b, &c, &d, &d[2])
出力:
0x21cd7c 0x21cd7c 0x21cd7c 0x21cd7c 0x21cd7c
すべてのアドレスが同じであり、これらのゼロにはメモリ割り当てがないことを示します。 -size 変数。
構造体フィールドの順序付けは、アライメント要件と理由によりサイズに影響を与える可能性があります。暗黙的なパディング。サイズがゼロの構造体は、メモリを割り当てず、個別の変数に同じアドレスを共有する可能性があるため、メモリ使用量を最適化します。
以上が構造体のフィールドの順序が Go 構造体のサイズに影響するのはなぜですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。