反射是一个接口,其定义如下:
type Type interface {
// 返回具体类型在内存分配时的字节分配方式
Align() int
// 返回具体类型在结构体中作为一个字段是内存对齐方式
FieldAlign() int
// 返回具体类型的第x个方法
Method(int) Method
// 根据函数名返回具体类型的方法
MethodByName(string) (Method, bool)
// 返回类型的方法个数
NumMethod() int
// 返回类型的名字
Name() string
// 返回类型的包名
PkgPath() string
// 返回类型所占内存字节大小
Size() uintptr
// 返回类型的简单描述,如:main.User
String() string
// 返回这个类型的Kind
Kind() Kind
// 检查类型是否实现了某个接口
//stringer := reflect.TypeOf((*fmt.Stringer)(nil)).Elem()
//fmt.Println(reflect.ValueOf(u).Type().Implements(stringer))
Implements(u Type) bool
// 检查类型是否可以被赋值给某个类型
AssignableTo(u Type) bool
// 检查类型是否可以转换到类型u
ConvertibleTo(u Type) bool
// 检查类型是否可比较
Comparable() bool
// 返回Int, Uint, Float, or Complex kinds.的字节大小
Bits() int
// 返回一个通道类型的方向
ChanDir() ChanDir
// 判断一个函数类型的最后一个参数是否是"..."参数
IsVariadic() bool
// 返回Array, Chan, Map, Ptr, or Slice类型的元素的类型
Elem() Type
// 返回结构体的第i个字段的详细信息
Field(i int) StructField
// 返回结构体内的嵌套结构体
FieldByIndex(index []int) StructField
// 根据名字返回结构体内的某个字段
FieldByName(name string) (StructField, bool)
// 根据match函数的返回值返回结构体内某个字段
FieldByNameFunc(match func(string) bool) (StructField, bool)
// 返回函数的第i个参数类型
In(i int) Type
// 返回map的键的类型
Key() Type
// 返回数组的长度
Len() int
// 返回结构体的字段个数
NumField() int
// 返回参数的入参个数
NumIn() int
// 返回函数的返回值个数
NumOut() int
// 返回函数第i个返回值的类型
Out(i int) Type
common() *rtype
uncommon() *uncommonType
}
从接口定义中我们可以知道:
对于所有的类型:
- 字节对齐方式
- 具体类型在内存分配时的字节分配方式
- 返回具体类型在结构体中作为一个字段是内存对齐方式
- 方法
- 具体类型的第x个方法
- 根据函数名获取具体类型的方法
- 检查类型是否实现了某个接口
- 基本信息
- 方法个数
- 类型名
- 类型包名
- 类型所占字节大小
- 类型的简单描述(如main.User)
- 获取类型的Kind
关于类型转换:
- 检查类型是否实现了某个接口
- 检查类型是否可以被赋值给某个类型
- 检查类型是否可以转换到类型u
对于通道:
- 获取通道的方向
- 获取通道内元素的类型
对于函数:
- 检查其最后一个参数是否是
...Type
类型 - 获取函数的入参、返回函数的返回值个数
- 根据下标获取函数入参、返回值的类型
对于结构体:
- 获取结构体的第i个字段的详细信息
- 获取结构体内的嵌套结构体
- 根据名字获取结构体内的某个字段
- 根据match函数的返回值获取结构体内某个字段
对于map:
- 获取map的键的类型
对于Array:
- 获取Array的长度
其他:
- 检查类型是否可比较