go学习part20(1)反射

283_尚硅谷_反射基本介绍和示意图_哔哩哔哩_bilibili

1.介绍

1)基本数据类型的类型和类别一致,但是结构体等不一样。

go学习part20(1)反射_第1张图片

 go学习part20(1)反射_第2张图片

 

2)反射的例子(桥连接,序列化)

go学习part20(1)反射_第3张图片

 序列化指定tag,会反射生成tag字符串

go学习part20(1)反射_第4张图片

 

3)reflect可以获取对象value和type值,value是一个结构体,type是一个接口。一个变量的type和value可以相互获取且都可以反过来操纵变量。

go学习part20(1)反射_第5张图片

 go学习part20(1)反射_第6张图片

三者关系

go学习part20(1)反射_第7张图片

 

4)一些概念

go学习part20(1)反射_第8张图片

转换关系图:

变量传给空接口形参,

go学习part20(1)反射_第9张图片

 go学习part20(1)反射_第10张图片

 

2.基本使用

1)

对reflect.Type输出是它内部封装的类型,对reflect.Value输出是它内部封装的值,但要注意它们虽然输出和int一样但是实际一个是Type接口一个是Value结构体。感觉有点像包装一个类型结构体然后绑定String()方法输出内部数值。实际类型是一个包装类型,但是输出内容的都是内部存储类型。

验证:对reflect.Value执行加int操作,系统报错,提示类型错误,表明reflect.ValueOf(b)的结果并不是int

2)想要取用reflect.Value内部的值,有两种方法

法一:Value结构体提供了许多方法可以直接修改或者读取内部的值,可以直接调用。

        修改:Value.Set类型(传参)

        读取:Value.类型()

法二:把Value转成interface{},然后再用断言转成其他类型。

        转interface{}:Value.Interface()

3)基本类型的反射

package main

import (
	"fmt"
	"reflect"
)

func reflectTest01(b interface{}) {
	//通过反射获取的传入的变量的 type , kind,值
	//感觉有点像包装一个类型结构体然后绑定String()方法输出内部数值。
	//实际类型是一个包装类型,但是输出内容的都是内部存储类型。
	//1。先获取到 reflect.Type
	rType := reflect.TypeOf(b)
	fmt.Println(rType) //真正类型是reflect.Type,但是输出会自动变成内部存储类型的实际类型int

	//2。先获取到 reflect.Value
	rVal := reflect.ValueOf(b)
	//报错cannot convert 2 (untyped int constant) to type struct{typ *reflect.rtype,
	//说明实际不是int类型而是reflect.Value
	//所以Value提供了很多方法去修改或者读取内部的值
	//n2 := 2 + rVal
	n2 := 2 + rVal.Int() //读取内部Int值
	fmt.Println(n2)
	fmt.Println(rVal) //真正类型是reflect.Value,但是输出会自动变成内部存储类型的实际值
	fmt.Printf("rVal内部数值:%v,rVal真正类型:%T\n", rVal, rVal)

	//3.将rVal转成interface{}
	iV := rVal.Interface() //把内部值按空接口类型输出
	//通过断言把interface{}转成需要的类型
	n3 := iV.(int)
	fmt.Println("n3=", n3)

}

func main() {
	演示对(基本数据类型、interface{(}、reflect.value)进行反射的基本操作
	var num int = 100
	reflectTest01(num)

}

 go学习part20(1)反射_第11张图片

 

4)结构体类型的反射

package main

import (
	"fmt"
	"reflect"
)


type Student struct {
	Name string
	Age  int
}

// 对结构体反射
func reflectTest02(b interface{}) {
	//1。先获取到 reflect.Type
	rType := reflect.TypeOf(b)
	fmt.Println(rType) //真正类型是reflect.Type,但是输出会自动变成内部存储类型的实际类型int

	//2。先获取到 reflect.Value
	rVal := reflect.ValueOf(b)

	//3.将rVal转成interface{}
	iV := rVal.Interface()                        //把内部值按空接口类型输出
	fmt.Printf("iV 内部数值:%v,iV 真正类型:%T\n", iV, iV) //运行看实际类型,所以输出的是Student类型
	//虽然运行输出可以,但是想调用Student内容是不行的,编译不知道底层实际类型,所以需要通过断言把interface{}转成需要的类型
	stu, ok := iV.(Student) //也可以switch
	if ok {
		fmt.Println("stu.Name=", stu.Name)
	}

}

func main() {
	演示对(基本数据类型、interface{(}、reflect.value)进行反射的基本操作)

	//2.定义结构体
	stu := Student{
		Name: "tom",
		Age:  20,
	}

	reflectTest02(stu)
}

你可能感兴趣的:(go学习,学习)