样例代码
5 type person struct {
6 name string
7 age int32
8 }
20 var var_person person = person{name:"abc",age:18}
23 var var_type reflect.Type = reflect.TypeOf(var_person)
25 mymethod,b := var_type.MethodByName("Test_MethodByName1")
对应汇编
0x023d 00573 (reflect.go:25) PCDATA $2, $5
0x023d 00573 (reflect.go:25) LEAQ ""..autotmp_91+2744(SP), DI
0x0245 00581 (reflect.go:25) XORPS X0, X0
0x0248 00584 (reflect.go:25) PCDATA $2, $0
0x0248 00584 (reflect.go:25) LEAQ -48(DI), DI
0x024c 00588 (reflect.go:25) DUFFZERO $277
0x025f 00607 (reflect.go:25) MOVQ "".var_type+952(SP), AX
0x0267 00615 (reflect.go:25) TESTB AL, (AX)
0x0269 00617 (reflect.go:25) MOVQ 176(AX), AX // 176 为MethodByName在Type接口方法中的偏移量
0x0270 00624 (reflect.go:25) PCDATA $2, $2
0x0270 00624 (reflect.go:25) MOVQ "".var_type+960(SP), CX //CX为动态类型person struct
0x0278 00632 (reflect.go:25) PCDATA $2, $0
0x0278 00632 (reflect.go:25) MOVQ CX, (SP) //将Type接口变量值(即动态类型)压入栈
0x027c 00636 (reflect.go:25) PCDATA $2, $2
0x027c 00636 (reflect.go:25) LEAQ go.string."Test_MethodByName1"(SB), CX
0x0283 00643 (reflect.go:25) PCDATA $2, $0
0x0283 00643 (reflect.go:25) MOVQ CX, 8(SP)
0x0288 00648 (reflect.go:25) MOVQ $18, 16(SP)
0x0291 00657 (reflect.go:25) CALL AX //调用方法 MethodByName(),具体实现见下文。
0x0293 00659 (reflect.go:25) PCDATA $2, $5
0x0293 00659 (reflect.go:25) PCDATA $0, $9
0x0293 00659 (reflect.go:25) LEAQ ""..autotmp_91+2744(SP), DI
0x029b 00667 (reflect.go:25) PCDATA $2, $6
0x029b 00667 (reflect.go:25) LEAQ 24(SP), SI
0x02a0 00672 (reflect.go:25) PCDATA $2, $0
0x02a0 00672 (reflect.go:25) DUFFCOPY $826
0x02b3 00691 (reflect.go:25) MOVBLZX 104(SP), AX
0x02b8 00696 (reflect.go:25) MOVB AL, ""..autotmp_92+115(SP)
0x02bc 00700 (reflect.go:25) PCDATA $2, $5
0x02bc 00700 (reflect.go:25) PCDATA $0, $10
0x02bc 00700 (reflect.go:25) LEAQ "".mymethod+2664(SP), DI
0x02c4 00708 (reflect.go:25) PCDATA $2, $6
0x02c4 00708 (reflect.go:25) PCDATA $0, $11
0x02c4 00708 (reflect.go:25) LEAQ ""..autotmp_91+2744(SP), SI
0x02cc 00716 (reflect.go:25) PCDATA $2, $0
0x02cc 00716 (reflect.go:25) DUFFCOPY $826
0x02df 00735 (reflect.go:25) MOVBLZX ""..autotmp_92+115(SP), AX
0x02e4 00740 (reflect.go:25) MOVB AL, "".b+114(SP)
//src\reflect\type.go
func (t *rtype) MethodByName(name string) (m Method, ok bool) {
if t.Kind() == Interface {
tt := (*interfaceType)(unsafe.Pointer(t))
return tt.MethodByName(name)
}
ut := t.uncommon()
if ut == nil {
return Method{}, false
}
// TODO(mdempsky): Binary search.
for i, p := range ut.exportedMethods() {
if t.nameOff(p.name).name() == name {
return t.Method(i), true
}
}
return Method{}, false
}
// MethodByName method with the given name in the type's method set.
func (t *interfaceType) MethodByName(name string) (m Method, ok bool) {
if t == nil {
return
}
var p *imethod
for i := range t.methods {
p = &t.methods[i]
if t.nameOff(p.name).name() == name {
return t.Method(i), true
}
}
return
}
type nameOff int32 // offset to a name
type typeOff int32 // offset to an *rtype
type textOff int32 // offset from top of text section
type name struct {
bytes *byte
}
func (t *rtype) nameOff(off nameOff) name {
return name{(*byte)(resolveNameOff(unsafe.Pointer(t), int32(off)))}
}
// resolveNameOff resolves a name offset from a base pointer.
// The (*rtype).nameOff method is a convenience wrapper for this function.
// Implemented in the runtime package.
func resolveNameOff(ptrInModule unsafe.Pointer, off int32) unsafe.Pointer
23 var var_type reflect.Type = reflect.TypeOf(var_person)
25 mymethod,b := var_type.MethodByName("Test_MethodByName1")
对应汇编
0x023d 00573 (reflect.go:25) LEAQ ""..autotmp_91+2744(SP), DI
0x0245 00581 (reflect.go:25) XORPS X0, X0
0x0248 00584 (reflect.go:25) PCDATA $2, $0
0x0248 00584 (reflect.go:25) LEAQ -48(DI), DI
0x024c 00588 (reflect.go:25) DUFFZERO $277
0x025f 00607 (reflect.go:25) MOVQ "".var_type+952(SP), AX
0x0267 00615 (reflect.go:25) TESTB AL, (AX)
0x0269 00617 (reflect.go:25) MOVQ 176(AX), AX
0x0270 00624 (reflect.go:25) PCDATA $2, $2
0x0270 00624 (reflect.go:25) MOVQ "".var_type+960(SP), CX
0x0278 00632 (reflect.go:25) PCDATA $2, $0
0x0278 00632 (reflect.go:25) MOVQ CX, (SP)
0x027c 00636 (reflect.go:25) PCDATA $2, $2
0x027c 00636 (reflect.go:25) LEAQ go.string."Test_MethodByName1"(SB), CX
0x0283 00643 (reflect.go:25) PCDATA $2, $0
0x0283 00643 (reflect.go:25) MOVQ CX, 8(SP)
0x0288 00648 (reflect.go:25) MOVQ $18, 16(SP)
0x0291 00657 (reflect.go:25) CALL AX
0x0293 00659 (reflect.go:25) PCDATA $2, $5
0x0293 00659 (reflect.go:25) PCDATA $0, $9
0x0293 00659 (reflect.go:25) LEAQ ""..autotmp_91+2744(SP), DI
0x029b 00667 (reflect.go:25) PCDATA $2, $6
0x029b 00667 (reflect.go:25) LEAQ 24(SP), SI
0x02a0 00672 (reflect.go:25) PCDATA $2, $0
0x02a0 00672 (reflect.go:25) DUFFCOPY $826
0x02b3 00691 (reflect.go:25) MOVBLZX 104(SP), AX
0x02b8 00696 (reflect.go:25) MOVB AL, ""..autotmp_92+115(SP)
0x02bc 00700 (reflect.go:25) PCDATA $2, $5
0x02bc 00700 (reflect.go:25) PCDATA $0, $10
0x02bc 00700 (reflect.go:25) LEAQ "".mymethod+2664(SP), DI
0x02c4 00708 (reflect.go:25) PCDATA $2, $6
0x02c4 00708 (reflect.go:25) PCDATA $0, $11
0x02c4 00708 (reflect.go:25) LEAQ ""..autotmp_91+2744(SP), SI
0x02cc 00716 (reflect.go:25) PCDATA $2, $0
0x02cc 00716 (reflect.go:25) DUFFCOPY $826
0x02df 00735 (reflect.go:25) MOVBLZX ""..autotmp_92+115(SP), AX
0x02e4 00740 (reflect.go:25) MOVB AL, "".b+114(SP)
tt := (*interfaceType)(unsafe.Pointer(t))
type iface struct {
tab *itab
data unsafe.Pointer
}
type itab struct {
inter *interfacetype
_type *_type
hash uint32 // copy of _type.hash. Used for type switches.
_ [4]byte
fun [1]uintptr // variable sized. fun[0]==0 means _type does not implement inter.
}
tt.MethodByName(name)
interfaceType.methods
保存了接口所有的方法。//src\reflect\type.go
// imethod represents a method on an interface type
type imethod struct {
name nameOff // name of method
typ typeOff // .(*FuncType) underneath
}
// interfaceType represents an interface type.
type interfaceType struct {
rtype
pkgPath name // import path
methods []imethod // sorted by hash
}
// src\runtime\type.go 与runtime变量名不同,结构完全一样
type interfacetype struct {
typ _type
pkgpath name
mhdr []imethod
}
// Method returns the i'th method in the type's method set.
func (t *interfaceType) Method(i int) (m Method) {
if i < 0 || i >= len(t.methods) {
return
}
p := &t.methods[i]
pname := t.nameOff(p.name)
m.Name = pname.name()
if !pname.isExported() {
m.PkgPath = pname.pkgPath()
if m.PkgPath == "" {
m.PkgPath = t.pkgPath.name()
}
}
m.Type = toType(t.typeOff(p.typ))
m.Index = i
return
}
methods
成员包含两个成员,name nameOff // name of method
和typ typeOff // .(*FuncType) underneath
Method
.func (t *rtype) nameOff(off nameOff) name {
return name{(*byte)(resolveNameOff(unsafe.Pointer(t), int32(off)))}
}
// resolveNameOff resolves a name offset from a base pointer.
// The (*rtype).nameOff method is a convenience wrapper for this function.
// Implemented in the runtime package.
func resolveNameOff(ptrInModule unsafe.Pointer, off int32) unsafe.Pointer
5 type person struct {
6 name string
7 age int32
8 }
21 var var_interface interface{} = person{name:"abc",age:18}
23 var var_type reflect.Type = reflect.TypeOf(var_interface)
对应汇编
0x00e0 00224 (reflect.go:23) PCDATA $2, $1
0x00e0 00224 (reflect.go:23) MOVQ "".var_interface+504(SP), AX
0x00e8 00232 (reflect.go:23) PCDATA $0, $1
0x00e8 00232 (reflect.go:23) MOVQ "".var_interface+496(SP), CX
0x00f0 00240 (reflect.go:23) PCDATA $0, $4
0x00f0 00240 (reflect.go:23) MOVQ CX, reflect.i+512(SP) // 接口类型
0x00f8 00248 (reflect.go:23) PCDATA $2, $0
0x00f8 00248 (reflect.go:23) MOVQ AX, reflect.i+520(SP) // 接口值
0x0100 00256 (reflect.go:23) XORPS X0, X0
0x0103 00259 (reflect.go:23) MOVUPS X0, "".~R0+352(SP)
0x010b 00267 (reflect.go:23) XCHGL AX, AX
0x010c 00268 (reflect.go:23) XORPS X0, X0
0x010f 00271 (reflect.go:23) MOVUPS X0, reflect.eface·3+672(SP)
// 对应源码 src\reflect\type.go
1374 func TypeOf(i interface{}) Type {
1375 eface := *(*emptyInterface)(unsafe.Pointer(&i))
1376 return toType(eface.typ)
1378 }
0x0117 00279 ($GOROOT/src/reflect/type.go:1375) PCDATA $2, $1
0x0117 00279 ($GOROOT/src/reflect/type.go:1375) LEAQ reflect.i+512(SP), AX
0x011f 00287 ($GOROOT/src/reflect/type.go:1375) PCDATA $2, $0
0x011f 00287 ($GOROOT/src/reflect/type.go:1375) TESTB AL, (AX)
0x0121 00289 ($GOROOT/src/reflect/type.go:1375) PCDATA $2, $1
0x0121 00289 ($GOROOT/src/reflect/type.go:1375) MOVQ reflect.i+520(SP), AX //接口值
0x0129 00297 ($GOROOT/src/reflect/type.go:1375) PCDATA $2, $3
0x0129 00297 ($GOROOT/src/reflect/type.go:1375) PCDATA $0, $1
0x0129 00297 ($GOROOT/src/reflect/type.go:1375) MOVQ reflect.i+512(SP), CX //接口类型,eface.typ 即*rtype
0x0131 00305 ($GOROOT/src/reflect/type.go:1375) MOVQ CX, reflect.eface·3+672(SP) //eface变量设置接口类型
0x0139 00313 ($GOROOT/src/reflect/type.go:1375) PCDATA $2, $2
0x0139 00313 ($GOROOT/src/reflect/type.go:1375) MOVQ AX, reflect.eface·3+680(SP) //eface变量设置接口值
0x0141 00321 ($GOROOT/src/reflect/type.go:1376) PCDATA $2, $0
0x0141 00321 ($GOROOT/src/reflect/type.go:1376) PCDATA $0, $5
0x0141 00321 ($GOROOT/src/reflect/type.go:1376) MOVQ CX, reflect.t+128(SP) //接口类型,首个元素
0x0149 00329 ($GOROOT/src/reflect/type.go:1376) XORPS X0, X0
0x014c 00332 ($GOROOT/src/reflect/type.go:1376) MOVUPS X0, "".~R0+448(SP)
0x0154 00340 ($GOROOT/src/reflect/type.go:1376) XCHGL AX, AX
3003 func toType(t *rtype) Type {
3004 if t == nil {
3005 return nil
3006 }
3007 return t
3008 }
0x0155 00341 ($GOROOT/src/reflect/type.go:3004) CMPQ reflect.t+128(SP), $0
0x015e 00350 (:0) JNE 357
0x0160 00352 (:0) JMP 3513
0x0165 00357 ($GOROOT/src/reflect/type.go:3007) PCDATA $2, $1
0x0165 00357 ($GOROOT/src/reflect/type.go:3007) PCDATA $0, $1
0x0165 00357 ($GOROOT/src/reflect/type.go:3007) MOVQ reflect.t+128(SP), AX
0x016d 00365 ($GOROOT/src/reflect/type.go:3007) MOVQ AX, ""..autotmp_45+216(SP)
0x0175 00373 ($GOROOT/src/reflect/type.go:1376) PCDATA $2, $3
0x0175 00373 ($GOROOT/src/reflect/type.go:1376) LEAQ go.itab.*reflect.rtype,reflect.Type(SB), CX //接口类型,即reflect.Type
0x017c 00380 ($GOROOT/src/reflect/type.go:1376) MOVQ CX, ""..autotmp_48+1056(SP)
0x0184 00388 ($GOROOT/src/reflect/type.go:1376) MOVQ AX, ""..autotmp_48+1064(SP)
0x018c 00396 ($GOROOT/src/reflect/type.go:1376) PCDATA $2, $1
0x018c 00396 ($GOROOT/src/reflect/type.go:1376) PCDATA $0, $6
0x018c 00396 ($GOROOT/src/reflect/type.go:1376) MOVQ CX, "".~R0+448(SP) //返回接口类型
0x0194 00404 ($GOROOT/src/reflect/type.go:1376) PCDATA $2, $0
0x0194 00404 ($GOROOT/src/reflect/type.go:1376) MOVQ AX, "".~R0+456(SP) //返回接口值
0x019c 00412 ($GOROOT/src/reflect/type.go:1376) JMP 414
0x019e 00414 (reflect.go:23) MOVQ "".~R0+448(SP), AX
0x01a6 00422 (reflect.go:23) PCDATA $2, $2
0x01a6 00422 (reflect.go:23) PCDATA $0, $1
0x01a6 00422 (reflect.go:23) MOVQ "".~R0+456(SP), CX
0x01ae 00430 (reflect.go:23) MOVQ AX, ""..autotmp_49+1040(SP) //临时变量,接口类型
0x01b6 00438 (reflect.go:23) MOVQ CX, ""..autotmp_49+1048(SP) //临时变量,接口值
0x01be 00446 (reflect.go:23) MOVQ AX, "".~R0+352(SP)
0x01c6 00454 (reflect.go:23) MOVQ CX, "".~R0+360(SP)
0x01ce 00462 (reflect.go:23) JMP 464
0x01d0 00464 (reflect.go:23) PCDATA $0, $7
0x01d0 00464 (reflect.go:23) MOVQ AX, "".var_type+480(SP)
0x01d8 00472 (reflect.go:23) PCDATA $2, $0
0x01d8 00472 (reflect.go:23) MOVQ CX, "".var_type+488(SP)
fmt.Println("type:",reflect.TypeOf(var_type));
//输出:type: *reflect.rtype
20 var var_person person = person{name:"abc",age:18}
23 var var_type reflect.Type = reflect.TypeOf(var_person)
25 method,b := var_type.MethodByName("Test_MethodByName1")
27 numMethod := var_type.NumMethod()
25行调用MethodByName
对应汇编
0x023d 00573 (reflect.go:25) PCDATA $2, $5
0x023d 00573 (reflect.go:25) LEAQ ""..autotmp_79+2416(SP), DI
0x0245 00581 (reflect.go:25) XORPS X0, X0
0x0248 00584 (reflect.go:25) PCDATA $2, $0
0x0248 00584 (reflect.go:25) LEAQ -48(DI), DI
0x024c 00588 (reflect.go:25) DUFFZERO $277
0x025f 00607 (reflect.go:25) MOVQ "".var_type+840(SP), AX
0x0267 00615 (reflect.go:25) TESTB AL, (AX)
0x0269 00617 (reflect.go:25) MOVQ 176(AX), AX // 将MethodByName方法地址放入 AX,var_type变量向后偏移176位置
//见下方 go.itab.*reflect.rtype,reflect.Type SRODATA dupok size=272
// rel 176+8 t=1 reflect.(*rtype).MethodByName+0
0x0270 00624 (reflect.go:25) PCDATA $2, $2
0x0270 00624 (reflect.go:25) MOVQ "".var_type+848(SP), CX
0x0278 00632 (reflect.go:25) PCDATA $2, $0
0x0278 00632 (reflect.go:25) MOVQ CX, (SP)
0x027c 00636 (reflect.go:25) PCDATA $2, $2
0x027c 00636 (reflect.go:25) LEAQ go.string."Test_MethodByName1"(SB), CX
0x0283 00643 (reflect.go:25) PCDATA $2, $0
0x0283 00643 (reflect.go:25) MOVQ CX, 8(SP)
0x0288 00648 (reflect.go:25) MOVQ $18, 16(SP)
0x0291 00657 (reflect.go:25) CALL AX // 调用MethodByName方法
0x0293 00659 (reflect.go:25) PCDATA $2, $5
0x0293 00659 (reflect.go:25) PCDATA $0, $9
0x0293 00659 (reflect.go:25) LEAQ ""..autotmp_79+2416(SP), DI
0x029b 00667 (reflect.go:25) PCDATA $2, $6
0x029b 00667 (reflect.go:25) LEAQ 24(SP), SI
0x02a0 00672 (reflect.go:25) PCDATA $2, $0
0x02a0 00672 (reflect.go:25) DUFFCOPY $826
0x02b3 00691 (reflect.go:25) MOVBLZX 104(SP), AX
0x02b8 00696 (reflect.go:25) MOVB AL, ""..autotmp_80+115(SP)
0x02bc 00700 (reflect.go:25) PCDATA $2, $5
0x02bc 00700 (reflect.go:25) PCDATA $0, $10
0x02bc 00700 (reflect.go:25) LEAQ "".method+2336(SP), DI
0x02c4 00708 (reflect.go:25) PCDATA $2, $6
0x02c4 00708 (reflect.go:25) PCDATA $0, $11
0x02c4 00708 (reflect.go:25) LEAQ ""..autotmp_79+2416(SP), SI
0x02cc 00716 (reflect.go:25) PCDATA $2, $0
0x02cc 00716 (reflect.go:25) DUFFCOPY $826
0x02df 00735 (reflect.go:25) MOVBLZX ""..autotmp_80+115(SP), AX
0x02e4 00740 (reflect.go:25) MOVB AL, "".b+114(SP)
//src\runtime\runtime2.go
type itab struct {
inter *interfacetype //8 字节
_type *_type //8 字节
hash uint32 //4 字节 copy of _type.hash. Used for type switches.
_ [4]byte //4 字节
fun [1]uintptr // 8 字节variable sized. fun[0]==0 means _type does not implement inter.
}
go.itab.*reflect.rtype,reflect.Type SRODATA dupok size=272
0x0000 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
0x0010 d6 c9 33 e3 00 00 00 00 00 00 00 00 00 00 00 00 ..3.............
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 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
0x0050 00 00 00 00 00 00 00 00 00 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 00 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 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
0x00b0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
0x00c0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
0x00d0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
0x00e0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
0x00f0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
0x0100 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
rel 0+8 t=1 type.reflect.Type+0 // itab.inter 接口类型
rel 8+8 t=1 type.*reflect.rtype+0 // itab._type 动态类型,即reflect.rtype
rel 24+8 t=1 reflect.(*rtype).Align+0 //itab.fun
rel 32+8 t=1 reflect.(*rtype).AssignableTo+0
rel 40+8 t=1 reflect.(*rtype).Bits+0
rel 48+8 t=1 reflect.(*rtype).ChanDir+0
rel 56+8 t=1 reflect.(*rtype).Comparable+0
rel 64+8 t=1 reflect.(*rtype).ConvertibleTo+0
rel 72+8 t=1 reflect.(*rtype).Elem+0
rel 80+8 t=1 reflect.(*rtype).Field+0
rel 88+8 t=1 reflect.(*rtype).FieldAlign+0
rel 96+8 t=1 reflect.(*rtype).FieldByIndex+0
rel 104+8 t=1 reflect.(*rtype).FieldByName+0
rel 112+8 t=1 reflect.(*rtype).FieldByNameFunc+0
rel 120+8 t=1 reflect.(*rtype).Implements+0
rel 128+8 t=1 reflect.(*rtype).In+0
rel 136+8 t=1 reflect.(*rtype).IsVariadic+0
rel 144+8 t=1 reflect.(*rtype).Key+0
rel 152+8 t=1 reflect.(*rtype).Kind+0
rel 160+8 t=1 reflect.(*rtype).Len+0
rel 168+8 t=1 reflect.(*rtype).Method+0
rel 176+8 t=1 reflect.(*rtype).MethodByName+0 //偏移176位置为MethodByName方法地址
rel 184+8 t=1 reflect.(*rtype).Name+0
rel 192+8 t=1 reflect.(*rtype).NumField+0
rel 200+8 t=1 reflect.(*rtype).NumIn+0
rel 208+8 t=1 reflect.(*rtype).NumMethod+0 //偏移208位置为NumMethod方法地址
rel 216+8 t=1 reflect.(*rtype).NumOut+0
rel 224+8 t=1 reflect.(*rtype).Out+0
rel 232+8 t=1 reflect.(*rtype).PkgPath+0
rel 240+8 t=1 reflect.(*rtype).Size+0
rel 248+8 t=1 reflect.(*rtype).String+0
rel 256+8 t=1 reflect.(*rtype).common+0
rel 264+8 t=1 reflect.(*rtype).uncommon+0
// uncommonType is present only for defined types or types with methods
// (if T is a defined type, the uncommonTypes for T and *T have methods).
// Using a pointer to this struct reduces the overall size required
// to describe a non-defined type with no methods.
type uncommonType struct {
pkgPath nameOff // import path; empty for built-in types like int, string
mcount uint16 // number of methods
xcount uint16 // number of exported methods
moff uint32 // offset from this uncommontype to [mcount]method
_ uint32 // unused
}
func (t *rtype) uncommon() *uncommonType {
if t.tflag&tflagUncommon == 0 {
return nil
}
switch t.Kind() {
case Struct:
return &(*structTypeUncommon)(unsafe.Pointer(t)).u
case Ptr:
type u struct {
ptrType
u uncommonType
}
return &(*u)(unsafe.Pointer(t)).u
case Func:
type u struct {
funcType
u uncommonType
}
return &(*u)(unsafe.Pointer(t)).u
case Slice:
type u struct {
sliceType
u uncommonType
}
return &(*u)(unsafe.Pointer(t)).u
case Array:
type u struct {
arrayType
u uncommonType
}
return &(*u)(unsafe.Pointer(t)).u
case Chan:
type u struct {
chanType
u uncommonType
}
return &(*u)(unsafe.Pointer(t)).u
case Map:
type u struct {
mapType
u uncommonType
}
return &(*u)(unsafe.Pointer(t)).u
case Interface:
type u struct {
interfaceType
u uncommonType
}
return &(*u)(unsafe.Pointer(t)).u
default:
type u struct {
rtype
u uncommonType
}
return &(*u)(unsafe.Pointer(t)).u
}
}