1 实现文件
gofrontend\libgo\go\reflect\type.go
gofrontend\libgo\go\reflect\value.go
这里定义了内部类型
src\reflect\type.go
src\runtime\type.go
2. reflect.Type
reflect.Type是一个interface.
type Type interface {
...
}
定义了一系列的方法。比如
2.1 公共方法
2.1.1 名称相关:
- 类型名称
Name() string
- 类型的字符串形式
String() string
2.1.2 类型相关:
- 类型的类型值
Kind() Kind
- 类型是否可以转换
ConvertibleTo(u Type) bool
2.1.3 方法相关:
- 获取第i个方法。
Method(int) Method
- 方法个数.
NumMethod() int
- 通过名称获取方法
MethodByName(string) (Method, bool)
2.2 不同类型特有方法
2.2.1 子元素类型 Array, Chan, Map, Ptr, or Slice 调用
- 返回内部子元素类型
Elem() Type
2.2.2 struct特有方法
- 获取第i个字段.
Field(i int) StructField
- 通过名称获取字段
FieldByName(name string) (StructField, bool)
- 字段个数。
NumField() int
2.2.3 map特有方法
- 返回key类型,
Key() Type
2.2.4 array特有方法
- 数组长度
Len() int
2.2.5 func特有方法
- 入参个数
NumIn() int
- 返回值个数
NumOut() int
- 第i个返回值类型
Out(i int) Type
- 第i个入参类型
In(i int) Type
2.2.6 chan特有方法
- chan方向
ChanDir() ChanDir
type ChanDir int
const (
RecvDir ChanDir = 1 << iota // <-chan
SendDir // chan<-
BothDir = RecvDir | SendDir // chan
)
// Create the main IR data structure.
type Type interface {
Align() int // 此类型的变量对齐后所占用的字节数
FieldAlign() int // 如果是struct的字段,对齐后占用的字节数
Method(int) Method // 返回类型方法集里的第 `i` (传入的参数)个方法
MethodByName(string) (Method, bool) // 通过名称获取方法
NumMethod() int // 获取类型方法集里导出的方法个数
Name() string // 类型名称
PkgPath() string // 返回类型所在的路径,如:encoding/base64
Size() uintptr // 返回类型的大小,和 unsafe.Sizeof 功能类似
String() string // 返回类型的字符串表示形式
Kind() Kind // 返回类型的类型值
Implements(u Type) bool // 类型是否实现了接口 u
AssignableTo(u Type) bool // 是否可以赋值给 u
ConvertibleTo(u Type) bool // 是否可以类型转换成 u
Comparable() bool // 类型是否可以比较
// 下面这些函数只有特定类型可以调用
// 如:Key, Elem 两个方法就只能是 Map 类型才能调用
Bits() int // 类型所占据的位数
ChanDir() ChanDir // 返回通道的方向,只能是 chan 类型调用
// 返回类型是否是可变参数,只能是 func 类型调用
// 比如 t 是类型 func(x int, y ... float64)
// 那么 t.IsVariadic() == true
IsVariadic() bool
Elem() Type // 返回内部子元素类型,只能由类型 Array, Chan, Map, Ptr, or Slice 调用
// 返回结构体类型的第 i 个字段,只能是结构体类型调用
// 如果 i 超过了总字段数,就会 panic
Field(i int) StructField
FieldByIndex(index []int) StructField // 返回嵌套的结构体的字段
FieldByName(name string) (StructField, bool) // 通过字段名称获取字段
// FieldByNameFunc returns the struct field with a name
// 返回名称符合 func 函数的字段
FieldByNameFunc(match func(string) bool) (StructField, bool)
In(i int) Type // 获取函数类型的第 i 个参数的类型
Key() Type // 返回 map 的 key 类型,只能由类型 map 调用
Len() int // 返回 Array 的长度,只能由类型 Array 调用
NumField() int // 返回类型字段的数量,只能由类型 Struct 调用
NumIn() int // 返回函数类型的输入参数个数
NumOut() int // 返回函数类型的返回值个数
Out(i int) Type // 返回函数类型的第 i 个值的类型
common() *rtype // 返回类型结构体的相同部分
uncommon() *uncommonType // 返回类型结构体的不同部分
}
3. Kind
- 使用Kind定义了内部所有类型,整数、布尔、字符串、map、slice、chan、struct等。
- 定义了每种Kind的字符串名称。
type Kind uint
const (
Invalid Kind = iota
Bool
Int
Int8
Int16
Int32
Int64
Uint
Uint8
Uint16
Uint32
Uint64
Uintptr
Float32
Float64
Complex64
Complex128
Array
Chan
Func
Interface
Map
Ptr
Slice
String
Struct
UnsafePointer
)
src\reflect\type.go
var kindNames = []string{
Invalid: "invalid",
Bool: "bool",
Int: "int",
Int8: "int8",
Int16: "int16",
Int32: "int32",
Int64: "int64",
Uint: "uint",
Uint8: "uint8",
Uint16: "uint16",
Uint32: "uint32",
Uint64: "uint64",
Uintptr: "uintptr",
Float32: "float32",
Float64: "float64",
Complex64: "complex64",
Complex128: "complex128",
Array: "array",
Chan: "chan",
Func: "func",
Interface: "interface",
Map: "map",
Ptr: "ptr",
Slice: "slice",
String: "string",
Struct: "struct",
UnsafePointer: "unsafe.Pointer",
}
4. reflect.rtype == runtime._type
reflect
定义了rtype
,作为所有类型的通用部分。 与runtime
中的_type
结构一致。
// rtype must be kept in sync with ../runtime/type.go:/^type._type.
type tflag uint8
type nameOff int32
type typeOff int32
type textOff int32
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 字节 0x08 8字节对象
fieldalign uint8 //1 字节 0x08 8字节对象
kind uint8 //1 字节 0x14=20=RUNTIME_TYPE_KIND_INTERFACE
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
}
4.1 chantype
type chantype struct {
typ _type
elem *_type
dir uintptr
}
4.2 maptype
type maptype struct {
typ _type
key *_type
elem *_type
bucket *_type // internal type representing a hash bucket
keysize uint8 // size of key slot
valuesize uint8 // size of value slot
bucketsize uint16 // size of bucket
flags uint32
}
4.3 arraytype
type arraytype struct {
typ _type
elem *_type
slice *_type
len uintptr
}
4.4 slicetype
type slicetype struct {
typ _type
elem *_type
}
4.5 functype
type functype struct {
typ _type
inCount uint16
outCount uint16
}
4.6 interfacetype
type interfacetype struct {
typ _type
pkgpath name
mhdr []imethod
}
4.7 ptrtype
type ptrtype struct {
typ _type
elem *_type
}
4.8 structtype
type structfield struct {
name name
typ *_type
offsetAnon uintptr
}
type structtype struct {
typ _type
pkgPath name
fields []structfield
}
// Method on non-interface type
type method struct {
name nameOff // name of method
mtyp typeOff // method type (without receiver)
ifn textOff // fn used in interface call (one-word receiver)
tfn textOff // fn used for normal method call
}
type imethod struct {
name nameOff
ityp typeOff
}