C語言中,能夠使用sizeof()計算變量或類型佔用的內存大小。在Go語言中,也提供了相似的功能, 不過只能查看變量佔用空間大小。具體使用舉例以下。程序員
package main import ( "fmt" "unsafe" ) type Man struct { Name string Age int } func main() { m := Man{Name:"John", Age:20} fmt.Println("man size:", unsafe.Sizeof(m)) fmt.Println("name size:", unsafe.Sizeof(m.Name)) fmt.Println("age size:", unsafe.Sizeof(m.Age)) }
output:golang
man size: 24
name size: 16
age size: 8c#
至少對於標準 Go 編譯器和 gccgo, 答案是確定的. 填充是操做系統和編譯器相關的.spa
好比:操作系統
type T1 struct { a int8 // 7 bytes padded on AMD64 OS and pad 3 bytes padded on i386 OS here b int64 c int16 // 6 bytes padded on AMD64 OS and pad 2 bytes padded on i386 OS here } type T2 struct { a int8 // 1 byte padded on both AMD64 and i386 OS here c int16 // 4 bytes padded on AMD64 OS here. No padding on i386 OS b int64 } |
T1.b
內存中的地址值在 AMD64 系統必須的是 8 字節對齊的, i386 系統是 4 字節對齊的. 這就是爲何 T1.a
在 AMD64 系統被填充 7 字節, 在 i386 系統被填充 3 字節.code
Go 規範對類型對齊作一些保證. 規則之一是一個結構體類型的對齊是它字段類型最大的那個的對齊. 因此 T1
也是 AMD64 系統 8 字節對齊, i386 系統 4 字節對齊(和 T1.b
類型同樣, int64
), 而且標準的 Go 編譯器將確保類型值的大小是該類型的對齊保證的倍數, 這就是爲何 T1.c
在 AMD64 系統被填充 6 字節, 在 i386 系統被填充 2 字節.內存
一個結構體中的字段順序會影響填充, 而且填充會影響後續結構體的大小. 在 AMD64 系統, T1
的大小是 24, 但 T2
的大小是 16.get
Go 編譯器不會重排結構體字段來減少結構體大小. 這樣作會引發一些不可預知的結果. 然而, 程序員能夠經過手動重排字段來減小填充.編譯器