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)

 

这里这个空接口类型不能直接和真正的整数相加减