非零基础自学Golang
第14章 反射
14.2 基本用法
在使用反射时,我们会经常使用到反射的种类(Kind),reflect.Kind在Go语言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。type A struct{}定义的结构体属于Struct种类,*A属于Ptr。
当我们使用反射获取到变量的类型时,就是用reflect.Kind来判断所属系统类型,举个例子:
[ 动手写14.2.1]
package main
import (
"fmt"
"reflect"
)
func main() {
var a int
typeOfA := reflect.TypeOf(a)
if typeOfA.Kind() == reflect.Int {
fmt.Printf("变量a 的Kind 是int")
} else {
fmt.Printf("变量a 的Kind 不是int")
}
}
动手写14.2.1定义了一个变量a,使用反射获取a的类型Kind与reflect.Int比较,运行结果如下:
14.2.1 获取类型信息
Go语言中使用reflect.TypeOf()来获取变量对象的类型信息,返回值的反射类型对象(reflect.Type),使用方法如下:
var typeOfNum reflect.Type = reflect.TypeOf(num)
获取类型名称可以使用reflect.Type中的Name()方法;获取类型的种类Kind,可以使用对应的Kind()方法;对于指针类型变量,可以使用reflect.Type中的Elem()来反射获取指针指向的元素类型。
[ 动手写 14.2.2]
package main
import (
"fmt"
"reflect"
)
type Number int
type Person struct {
}
func checkType(t reflect.Type) {
if t.Kind() == reflect.Ptr {
fmt.Printf("变量的类型名称 %v , 指向的变量为: ", t.Kind())
t = t.Elem()
}
fmt.Printf("变量的类型名称 => %v , 类型种类 => %v \n", t.Name(), t.Kind())
}
func main() {
var num Number = 10
typeOfNum := reflect.TypeOf(num)
fmt.Println("typeOfNum")
checkType(typeOfNum)
var person Person
typeOfPerson := reflect.TypeOf(person)
fmt.Println("typeOfPerson")
checkType(typeOfPerson)
typeOfPersonPtr := reflect.TypeOf(&person)
fmt.Println("typeOfPersonPtr")
checkType(typeOfPersonPtr)
}
动手写14.2.2中,定义了int种类的Number类型和一个Person结构体类型。
checkType()函数对传入的reflect.Type变量进行判断,如果变量的种类为指针类型,就输出类型种类,并获取其指向的元素,输出类型名和类型Kind。
运行结果如下: