Go part 7 反射

反射

反射是指在程序运行期间对程序本身进行访问和修改的能力,(程序在编译时,变量被转换为内存地址,变量名不会被编译器写入到可执行部分,在运行程序时,程序无法获取自身的信息)

支持反射的语言可以在程序编译期间将变量的反射信息,如字段名称、类型等信息整合到可执行文件中,并给程序提供接口访问反射信息,这样就可以在程序运行期间获取类型的反射信息,并且有能力修改它们

Go 程序在运行期间使用 reflect 包访问程序的反射信息

像 Python,JavaScript 类动态语言,由于本身的语法特性就可以让代码运行期间访问程序自身的值和类型信息,因此不需要反射系统

 

通过反射获取类型信息

使用 reflect.TypeOf() 函数可以获取变量的类型对象(reflect.Type)

通过类型对象可以获取自身的类型信息,使用 Name() 方法获取类型名称,使用 Kind() 方法获取类型归属的种类 

package main
import (
	"fmt"
	"reflect"
)

func GetReflectInfo(a interface{}) {
	// 获取变量 a 的类型对象,类型对象的类型是 reflect.Type
	var typeOfA reflect.Type = reflect.TypeOf(a)
	fmt.Printf("%T\n", typeOfA)
        // 打印类型名 和 种类
	fmt.Println(typeOfA.Name(), typeOfA.Kind())
}

func main() {
	GetReflectInfo("666")
}

运行结果:
*reflect.rtype
string string

发现类型和种类都是 string,很奇怪是不是,接着看下面的例子 ...

 

理解反射的类型(Type)和种类(Kind)

编程中,使用最多的是类型,但在反射中,当需要区分一个大品种的类型时,就会用到种类(Kind)

1)类型(Type)

类型指的是系统原生数据类型,如 int、string、bool、float32 等类型,以及使用 type 关键字自定义的类型,自定义类型需要指定类型名称,例如,type A struct {},类型名就是 A

 

2)种类(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

type A struct{} 结构体属于 Struct 种类,*A 属于 Ptr 种类

 

3)从自定义的类型对象中获取类型名称和类型种类(加强理解)

package main

import (
	"fmt"
	"reflect"
)

type Cat struct{}
type Enum int

func main(){
	var cat Cat = Cat{}
	var num Enum = 1

	//对 cat 变量使用反射
	var typeOfCat reflect.Type= reflect.TypeOf(cat)
	fmt.Println(typeOfCat.Name(), typeOfCat.Kind())

	//对 num 变量使用反射
	typeOfNum := reflect.TypeOf(num)
	fmt.Println(typeOfNum.Name(), typeOfNum.Kind())
}

运行结果:
Cat struct
Enum int

  

 

上一篇:肯德基收银系统java


下一篇:Ubuntu下搭建Kubernetes集群(4)--部署K8S Dashboard