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
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
|
package main
import (
"fmt"
"unsafe"
)
type sType struct {
size uintptr // 当前类型占用字节大小 B
ptrData uintptr // 类型中也可包含指针的字节数 B 在当前大小范围后都是标量数据
hash uint32 // 类型唯一哈希值
tFlag uint8 // 记录着当前类型的额外信息,比如名称、方法集、名称*前缀、包路径、tag标签等
align uint8 // 类型的对齐量
fieldAlign uint8 // 结构体字段的对齐量
kind uint8 // 类型枚举
equal func(uintptr, uintptr) // 类型比较函数
gcData *byte // 垃圾回收相关
str int32 // 当前类型name的偏移量
ptrToThis int32 // 当前类型的指针类型的偏移量
}
// 数组元类型
type arrayType struct {
sType
elem *sType
slice *sType
len uintptr
}
// 自定义数组类型,包含自定义方法
type u struct {
arrayType
uncommonType
}
// 自定义方法集
type uncommonType struct {
pkgPath int32 // 4B 偏移到表名称路径
mCount uint16 // 2B 总方法数量
xCount uint16 // 2B 可导出方法数量
mOff uint32 // 4B 偏移到首方法的偏移量,方法是按照方法名正序排序的,因此导出方法在最前面
_ uint32 // 4B 占位内存补齐
}
// AA 定义自定义类型
type AA [2]uint8
func (a AA) String() string {
return "可导出方法"
}
func (a *AA) setName(i uint8) {
a[0] = i // 这里是语法糖 (*a)[0] = 1
}
// ptrType represents a pointer type. 指针类型
type ptrType struct {
sType
elem *sType // pointer element (pointed at) type
}
type up struct {
ptrType
uncommonType
}
func main() {
// 验证自定义类型
var a AA
a.setName(12)
// AA类型
var inter any = a // 该类型只实现了String方法
s := **(**u)(unsafe.Pointer(&inter))
fmt.Printf("%#v\n", s)
// *AA类型 是指针类型
var inter1 any = &a // 该类型只实现了setName方法,但是还有编译包装的*AA String()方法
s1 := **(**up)(unsafe.Pointer(&inter1))
fmt.Printf("%#v\n", s1)
}
// kind: 0x11 是 17 array类型
// AA类型
// main.u{
// arrayType:main.arrayType{
// sType:main.sType{
// size:0x2,
// ptrData:0x0,
// hash:0xeb895ab,
// tFlag:0xf,
// align:0x1,
// fieldAlign:0x1,
// kind:0x11,
// equal:(func(uintptr, uintptr))(0xb02c40),
// gcData:(*uint8)(0xbc8010),
// str:4503,
// ptrToThis:45344
// },
// elem:(*main.sType)(0xb94e20),
// slice:(*main.sType)(0xb93f20),
// len:0x2
// },
// uncommonType:main.uncommonType{
// pkgPath:522,
// mCount:0x1, // 方法总数1
// xCount:0x1,
// mOff:0x10,
// _:0x0
// }
// }
// kind: 0x36 是 54 = 32(类型间接存在接口值中) + 22(指针类型)
// *AA类型
// main.up{
// ptrType:main.ptrType{
// sType:main.sType{
// size:0x8,
// ptrData:0x8,
// hash:0xae85f2d0,
// tFlag:0x9, // 1001
// align:0x8,
// fieldAlign:0x8,
// kind:0x36, // 0x36 = 54 = 32 + 22
// equal:(func(uintptr, uintptr))(0x9f2c80),
// gcData:(*uint8)(0xab8330),
// str:4512,
// ptrToThis:0
// },
// elem:(*main.sType)(0xa88fc0)
// },
// uncommonType:main.uncommonType{
// pkgPath:522,
// mCount:0x2, // 方法总数2
// xCount:0x1,
// mOff:0x10,
// _:0x0
// }
// }
|