go 反射 type 和 kind 的区别
先试着运行下面的代码,根据运行结果思考:
package main
import (
"fmt"
"reflect"
)
// Type(电视机)是类型, Kind(家用电器)是类别
// 通常基础数据类型的 Type 和 Kind 相同,自定义数据类型则不同
type ms string
type cat struct {
}
func main() {
var a ms
var b cat
typeOfA := reflect.TypeOf(a) // 获取类型对象
fmt.Println(typeOfA.Name(), typeOfA.Kind()) // 类型名称与类型种类
typeOfCat := reflect.TypeOf(b) // 获取结构体实例的反射类型对象
fmt.Println(typeOfCat.Name(), typeOfCat.Kind()) // 显示反射类型对象的名称和种类
}
上方代码运行,结果如下。
根据结果,可以理解为 kind 是更底层的类型,即使你给类型起了个别名,如
type ms string
type 获取到的是 ms,但是 kind 还是能一眼看出是 string(大威天龙,手动滑稽)
Go语言程序中的类型(Type)指的是系统原生数据类型,如 int、string、bool、float32 等类型,以及使用 type 关键字定义的类型,这些类型的名称就是其类型本身的名称。
种类(Kind)指的是对象归属的品种。
例如使用 type A struct{} 定义结构体时,A 就是类型,struct 就是 种类。
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 // 底层指针
)
Map、Slice、Chan 属于引用类型,用起来像是指针一样,但却是独立的类型,不属于 Ptr。
定义变量 var ch = make(chan int) ,ch 属于 Chan 种类,*ch 属于 Ptr 种类。