go学习之类型的数据结构内存分布

想知道go的数据类型在内存中是怎么分布的,一个有趣的了解方式,那就是panic

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
package main
type AA struct {
A string
B map[string]string
}
func main() {
retFunc("1", []rune("222"), nil, AA{})
}
func retFunc(s string, sl []rune, it interface{}, a AA) int {
panic("ret int")
return 0
}

运行

如上代码运行,两次函数中的panic打印中函数调用的栈信息
从中我们关注函数参数部分(注意panic限制展示参数10个,超过不显示)

main.retFunc(0x9edcf, 0x1, 0x1042ff9c, 0x3, 0x3, 0x0, 0x0, 0x0, 0x0, 0x0, ...)

和函数声明个数不一致
retFunc(s string, sl []rune, it interface{}, a AA) int

这里我们可以减少函数参数类型,一个个去试,对应数据类型的内存分布就都能发现了

这里直接看结果

  • map 有一个域
  • string 有两个域 (一个指向字符串数据的指针和一个长度)
  • slice 有三个域 (一个指向底层数组的指针,一个长度,一个容量)
  • interface 有两个域 (一个指向类型的指针和一个指向值的指针)
  • struct 按其每个field的内存分布依次排列

所以上边retFunc的panic中

1
2
3
4
5
6
7
main.retFunc(
0x9edcf, 0x1, //string s的地址及长度
0x1042ff9c, 0x3, 0x3, //slice sl的地址,长度,容量
0x0, 0x0, //interface it的类型地址,和值地址
0x0, 0x0, 0x0, //struct a的string AA的地址,长度,map B的地址
... //(被隐藏)返回值 int
)

附录
理解 Go 语言中的 panic 输出
godata
interface

如有疑问,请留言或邮件newbvirgil@gmail.com
本文链接 : http://blog.newbmiao.com/2018/03/15/go-value-layout-in-memory.html