Go语言编程基础:反射

82 阅读1分钟
反射可以在运行时动态获取变量的各种信息。
通过反射,还可以修改变量的值,调用相关联的方法。
使用反射需要reflect包。
reflect.TypeOf(变量名):获取变量的类型,返回reflect.Type类型
reflect.ValueOf(变量名):获取变量值,返回reflect.Value类型

需要注意的是:变量,interface{},reflect.Value是可以相互转换的。
一般的步骤是:变量->interface{}->reflect.Value->变量。

示例:
package main

import (
	"fmt"
	"reflect"
)

type Student struct {
	Name string
	Age int
}

//演示对基本数据类型int的反射
func reflectTest1(b interface{} ) {
	rTyp := reflect.TypeOf(b) //获取变量类型
	fmt.Println("rType =", rTyp)

	rVal := reflect.ValueOf(b) //获取变量值

	n2 := 2 + rVal.Int() //reflect.Value强转为int(因为这是演示我们知道我会传入int变量)
	fmt.Println("n2 =", n2)

}

//演示对结构体类型数据的反射
func reflectTest2(b interface{} ) {
	rTyp := reflect.TypeOf(b)
	fmt.Println("rType =", rTyp)

	rVal := reflect.ValueOf(b)

	iV := rVal.Interface() //强转为interface{}
	fmt.Printf("iv = %v ; ivType = %T\n", iV, iV) //断言
        //通过断言我们可以知道iV在传直接来前的类型和值

	stu, ok := iV.(Student)
	if ok {
		fmt.Printf("stu.Name=%v\n", stu.Name)
	}

}

func main() {
	reflectTest1(1)

	stu := Student{
		Name : "tom",
		Age : 20,
	}
	reflectTest2(stu)
}
reflect.Value.Kind可以获取变量的类别
TypeKind可能相同也可能不同(取决于不同的数据类型)
比如:var num int = 10 num的TypeKind就都是int
比如:var stu Student  stu的Type是包名.StudentKind是struct

通过反射的来修改变量, 注意当使用 Set?...? 方法时,必须
通过对应的指针类型来完成, 这样才能改变传入的变量的值。
我们通过 reflect.Value.Elem()获取该数据的指针
示例:
    var num = 100
    fn := reflect.ValueOf(&num)
    fn.Elem().SetInt(200)