>

Go 语言虽然作为一个编译型语言,但是它却没有提供类似 C/C++ 中那样的 sizeof 关键字来查看某个类型变量的所占内存空间的大小。不过,Go 标准库提供了一个 unsafe 包,这个包提供一个 Sizeof() 函数,我们可以使用这个函数来获得一个类型所占内存大小。unsafe 包中只有一个文件 unsafe.go,这个文件中只声明了 5 个函数,而这五个函数的实现都是用汇编代码实现的。

提示: 如果要在实际项目中使用 unsafe 包,需要非常谨慎,因为使用 unsafe 包之后可能会导致代码失去平台兼容性。

unsafe.go 中的内容:

1
2
3
4
5
6
7
type ArbitraryType int

func Alignof(x ArbitraryType) uintptr
func Offsetof(x ArbitraryType) uintptr
func Sizeof(x ArbitraryType) uintptr
type ArbitraryType
type Pointer

写一个程序来测试:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
package main

import (
"fmt"
"unsafe"
)

type Post struct {
B []byte
Title string
I32 int32
I64 int64
I int
IsBool bool
}

type Entity interface {
Print()
Info() string
}

var ent Entity

func testSize() {
var pst Post
fmt.Println("sizeof struct: ", unsafe.Sizeof(pst))
fmt.Println("sizeof byte: ", unsafe.Sizeof(pst.B))
fmt.Println("sizeof string: ", unsafe.Sizeof(pst.Title))
fmt.Println("sizeof int32: ", unsafe.Sizeof(pst.I32))
fmt.Println("sizeof int64: ", unsafe.Sizeof(pst.I64))
fmt.Println("sizeof int: ", unsafe.Sizeof(pst.I))
fmt.Println("sizeof bool: ", unsafe.Sizeof(pst.IsBool))
}

func testEntity() {
fmt.Println("sizeof entity: ", unsafe.Sizeof(ent))
}

func testInterface(in interface{}) {
fmt.Println("sizeof interface{}: ", unsafe.Sizeof(in))
}

func testMap() {
var i map[string]int
fmt.Println("sizeof map: ", unsafe.Sizeof(i))
}

func main() {
testSize()
testMap()
testInterface(1)
testInterface(int64(1))
testEntity()
}

输出结果:

sizeof struct: 72
sizeof byte: 24
sizeof string: 16
sizeof int32: 4
sizeof int64: 8
sizeof int: 8
sizeof bool: 1
sizeof map: 8
sizeof interface{}: 16
sizeof interface{}: 16
sizeof entity: 16