07-go数据类型内存结构-struct

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
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值