Go语言中的反射是由 reflect 包提供支持的,它定义了两个重要的类型 Type 和 Value 。任意值在反射中都可以理解为由 reflect.Type 和 reflect.Value 两部分组成,并且 reflect 包提供了 reflect.TypeOf 和 reflect.ValueOf 两个函数来获取任意对象的 Value 和 Type。
在Go语言程序中,使用 reflect.TypeOf() 函数可以获得任意值的类型对象(reflect.Type),程序通过类型对象可以访问任意值的类型信息。
Type 和 Kind 的区别Type 是类型。Kind 是类别。Type 和 Kind 可能相同,也可能不同。通常基础数据类型的 Type 和 Kind 相同,自定义数据类型则不同。
基础类型
输出结果为 int int
func main() {
var a int
typeA := reflect.TypeOf(a)
fmt.Println(typeA.Name(), typeA.Kind())
}
自定义类型
输出结果为cat struct
type cat struct {
name string
}
typeCat := reflect.TypeOf(cat{})
fmt.Println(typeCat.Name(), typeCat.Kind())
对于反射中的 kind 我们既可以通过 reflect.Type 来获取,也可以通过 reflect.Value 来获取。他们得到的值和类型均是相同的。
种类(Kind)
种类(Kind)指的是对象归属的品种,在 reflect 包中有如下定义:
type Kind uint
const (
Invalid Kind = iota // 非法类型
Bool // 布尔型
Int // 有符号整型
Int8 // 有符号8位整型
Int16 // 有符号16位整型
Int32 // 有符号32位整型
Int64 // 有符号64位整型
Uint // 无符号整型
Uint8 // 无符号8位整型
Uint16 // 无符号16位整型
Uint32 // 无符号32位整型
Uint64 // 无符号64位整型
Uintptr // 指针
Float32 // 单精度浮点数
Float64 // 双精度浮点数
Complex64 // 64位复数类型
Complex128 // 128位复数类型
Array // 数组
Chan // 通道
Func // 函数
Interface // 接口
Map // 映射
Ptr // 指针
Slice // 切片
String // 字符串
Struct // 结构体
UnsafePointer // 底层指针
)
总结
相较于 Type 而言,Kind 所表示的范畴更大。可以理解为数学中的包含关系。类似于家用电器(Kind)和电视机(Type)之间的对应关系。类似于电商系统中的spu和sku的关系一样。