1. 反射的应用场景:结构体的序列化和反序列化

反射的基本介绍:
1.反射可以在运行时动态的获取变量的各种信息,比如变量的类型(type),类别(kind)。
2.如果是结构体变量,还可以获取到结构体本身的信息(包括结构体的字段,方法)
3.通过反射,可以修改变量的值,还可以调用关联的方法
4.使用反射需要import reflect
reflect包实现了运行时反射,允许程序操作任意类型的对象。典型用法是用静态类型interface}保存一个值,调用TypeOf获取其动态类型信息,该函数返回一个Type类型值。调用ValueOf函数返回一个Value类型值,该值代表运行时的数据。Zero接受一个Type类型参数并返回一个代表该类型零值的Value类型值。
TypeOf
func TypeOf(i interface{}) Type
//TypeOf返回接口中保存的值的类型,TypeOf(nil)会返回nil
1.reflect.TypeOf(变量名),获取变量的类型,返回reflect.Type类型。
2.reflect.ValueOf(变量名),获取变量的值,返回reflect.Value类型,reflect.Value是一个结构体类型。
var student Stu
func test(b interface{}){
//1.如何将interface{}转成reflect.Value
rVal := reflect.ValueOf(b)
//2.如何将reflect.Value -> interface{}
iVal := rVal.Interface()
//3.如何将interface{}转成原来的变量类型,使用类型断言
v := iVal.(Stu)
}
反射的实例:
func reflectTest01(b interface{}) {
//为什么要用接口类型呢,因为要对任何类型进行反射
//通过反射获取到传入的变量的type,kind,值
//1.先获取到reflect.Type
rTyp := reflect.TypeOf(b)
fmt.Println("rType=", rTyp)
//2.获取到reflect.Value
rVal := reflect.ValueOf(b)
fmt.Println("rVal=", rVal)
//虽然看着这个值是100而且是int类型,但是其实并不是
n2 := 100 + rVal
fmt.Println(n2)
}
在反射中,看着是int类型的但是其实不是。 并不能和真正的int来进行相加减。

打印其真正的类型,发现并不是普通的int类型
而是reflect.Value类型。

如果想要获得到真正的int类型的值,需要调用int方法。

转回去:
intf := rVal.Interface()
fmt.Printf("intf=%v intf Type=%T\n", intf, intf)
n2 := 100 + intf
num2 := intf.(int)
fmt.Printf("num2=%v num2 Type=%T\n", num2, num2)
这里这个空接口类型不能直接和真正的整数相加减
