struct 为所有成员依次存放。
1. 普通struct
type student struct {
name string
age int64
height int32
weight int
}
func (stu student) Name() string{
return stu.name
}
var stu student = student{name:"aaa",age:0x18,height:0x180,weight:0x60}
var stu1 student = student{name:"bbb",age:0x28}
var stu2 student = student{"ccc",0x38,0x181,0x61}
func main() {
var stu3 student = stu
}
"".stu SDATA size=40
0x0000 00 00 00 00 00 00 00 00 03 00 00 00 00 00 00 00 ................
0x0010 18 00 00 00 00 00 00 00 80 01 00 00 00 00 00 00 ................
0x0020 60 00 00 00 00 00 00 00 `.......
rel 0+8 t=1 go.string."aaa"+0
"".stu1 SDATA size=40
0x0000 00 00 00 00 00 00 00 00 03 00 00 00 00 00 00 00 ................
0x0010 28 00 00 00 00 00 00 00 (.......
rel 0+8 t=1 go.string."bbb"+0
"".stu2 SDATA size=40
0x0000 00 00 00 00 00 00 00 00 03 00 00 00 00 00 00 00 ................
0x0010 38 00 00 00 00 00 00 00 81 01 00 00 00 00 00 00 8...............
0x0020 61 00 00 00 00 00 00 00 a.......
rel 0+8 t=1 go.string."ccc"+0
//stu3 = stu1
0x0032 00050 (struct-type.go:23) MOVQ "".stu(SB), AX
0x0039 00057 (struct-type.go:23) MOVQ AX, "".stu3+504(SP)
0x0041 00065 (struct-type.go:23) MOVUPS "".stu+8(SB), X0
0x0048 00072 (struct-type.go:23) MOVUPS X0, "".stu3+512(SP)
0x0050 00080 (struct-type.go:23) MOVUPS "".stu+24(SB), X0
0x0057 00087 (struct-type.go:23) MOVUPS X0, "".stu3+528(SP)
2. struct嵌套
type contact struct {
name string
phone int64
}
type student struct {
name string
age int64
height int64
weight int64
}
type student2 struct {
contact contact
name string
age int64
height int64
weight int64
}
var var_stu student2 = student2{contact:contact{name:"father",phone:0x186},name:"aaa",age:0x18,height:0x180,weight:0x60}
对应汇编,可以看出也是按成员依次存放。
"".var_stu SDATA size=64
0x0000 00 00 00 00 00 00 00 00 06 00 00 00 00 00 00 00 ................
0x0010 86 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
0x0020 03 00 00 00 00 00 00 00 18 00 00 00 00 00 00 00 ................
0x0030 80 01 00 00 00 00 00 00 60 00 00 00 00 00 00 00 ........`.......
rel 0+8 t=1 go.string."father"+0
rel 24+8 t=1 go.string."aaa"+0
3. struct tag
type User struct {
Id int `json:"id"`
Name string `json:"name"`
}
var user User = User{Id:0x1234,Name:"dddd"}
添加了tag,数据部分内存依然是按顺序存放.
"".user SDATA size=24
0x0000 34 12 00 00 00 00 00 00 00 00 00 00 00 00 00 00 4...............
0x0010 04 00 00 00 00 00 00 00 ........
rel 8+8 t=1 go.string."dddd"+0
4. sturct底层结构
4.1 structtype
type structtype struct {
typ _type
pkgPath name
fields []structfield
}
type name struct {
bytes *byte
}
4.2 structfield
//src\runtime\type.go
type structfield struct {
name name
typ *_type
offsetAnon uintptr
}
4.3 _type
//src\runtime\type.go
// Needs to be in sync with ../cmd/link/internal/ld/decodesym.go:/^func.commonsize,
// ../cmd/compile/internal/gc/reflect.go:/^func.dcommontype and
// ../reflect/type.go:/^type.rtype.
type _type struct { //共48字节
size uintptr //8字节
ptrdata uintptr //8字节 size of memory prefix holding all pointers
hash uint32 //4字节
tflag tflag //1字节
align uint8 //1字节
fieldalign uint8 //1字节
kind uint8 //1字节
alg *typeAlg //8字节
// gcdata stores the GC type data for the garbage collector.
// If the KindGCProg bit is set in kind, gcdata is a GC program.
// Otherwise it is a ptrmask bitmap. See mbitmap.go for details.
gcdata *byte //8字节
str nameOff //4字节
ptrToThis typeOff //4字节
}
type tflag uint8
type nameOff int32
type typeOff int32
type textOff int32
// typeAlg is also copied/used in reflect/type.go.
// keep them in sync.
type typeAlg struct {
// function for hashing objects of this type
// (ptr to object, seed) -> hash
hash func(unsafe.Pointer, uintptr) uintptr
// function for comparing objects of this type
// (ptr to object A, ptr to object B) -> ==?
equal func(unsafe.Pointer, unsafe.Pointer) bool
}
4.4 struct类型信息内存结构
可以看出
type..namedata.age- SRODATA dupok size=6
0x0000 00 00 03 61 67 65 ...age
type..namedata.height- SRODATA dupok size=9
0x0000 00 00 06 68 65 69 67 68 74 ...height
type."".student SRODATA size=144
0x0000 10 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
0x0010 84 56 eb b4 07 08 08 99 00 00 00 00 00 00 00 00 .V..............
0x0020 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
0x0030 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
0x0040 02 00 00 00 00 00 00 00 02 00 00 00 00 00 00 00 ................
0x0050 00 00 00 00 00 00 00 00 40 00 00 00 00 00 00 00 ........@.......
0x0060 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
0x0070 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
0x0080 00 00 00 00 00 00 00 00 10 00 00 00 00 00 00 00 ................
rel 24+8 t=1 runtime.algarray+96 // _type.alg
rel 32+8 t=1 runtime.gcbits.+0 //_type.gcdata
rel 40+4 t=5 type..namedata.*main.student-+0 //_type.str
rel 44+4 t=5 type.*"".student+0 //_type.ptrToThis _type结束
rel 48+8 t=1 type..importpath."".+0 //structtype.pkgPath
rel 56+8 t=1 type."".student+96
rel 80+4 t=5 type..importpath."".+0
//以下是structfield数组成员
rel 96+8 t=1 type..namedata.age-+0 //structfield.name
rel 104+8 t=1 type.int64+0 //structfield.type
//structfield.offsetAnon
rel 120+8 t=1 type..namedata.height-+0 //structfield.name
rel 128+8 t=1 type.int64+0 //structfield.type
//structfield.offsetAnon
4.5 struct 方法
type student struct {
name string
age int64
height int64
weight int64
}
func (stu student) Name() string{
return stu.name
}
增加方法后,在student的类型信息中会添加对应方法的描述信息。
type."".student SRODATA size=208
0x0000 28 00 00 00 00 00 00 00 08 00 00 00 00 00 00 00 (...............
0x0010 84 56 eb b4 07 08 08 19 00 00 00 00 00 00 00 00 .V..............
0x0020 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
0x0030 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
0x0040 04 00 00 00 00 00 00 00 04 00 00 00 00 00 00 00 ................
0x0050 00 00 00 00 01 00 01 00 70 00 00 00 00 00 00 00 ........p.......
0x0060 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
0x0070 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
0x0080 00 00 00 00 00 00 00 00 20 00 00 00 00 00 00 00 ........ .......
0x0090 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
0x00a0 30 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0...............
0x00b0 00 00 00 00 00 00 00 00 40 00 00 00 00 00 00 00 ........@.......
0x00c0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
rel 24+8 t=1 type..alg."".student+0
rel 32+8 t=1 runtime.gcbits.01+0
rel 40+4 t=5 type..namedata.*main.student-+0
rel 44+4 t=5 type.*"".student+0
rel 48+8 t=1 type..importpath."".+0
rel 56+8 t=1 type."".student+96
rel 80+4 t=5 type..importpath."".+0
rel 96+8 t=1 type..namedata.name-+0
rel 104+8 t=1 type.string+0
rel 120+8 t=1 type..namedata.age-+0
rel 128+8 t=1 type.int64+0
rel 144+8 t=1 type..namedata.height-+0
rel 152+8 t=1 type.int64+0
rel 168+8 t=1 type..namedata.weight-+0
rel 176+8 t=1 type.int64+0
//Name方法描述信息
rel 192+4 t=5 type..namedata.Name.+0
rel 196+4 t=24 type.func() string+0
rel 200+4 t=24 "".(*student).Name+0
rel 204+4 t=24 "".student.Name+0