一、反射
1、反射可以在运行时动态获取变量的各种信息,比如变量的类型(type),类别(kind)
2、如果是结构体变量,还可以获取到结构体本身的信息(包括结构体的字段、方法)
3、通过反射,可以修改变量的值,可以调用关联的方法。
4、使用反射,需要import ("reflect")
二、反射示意图
三、反射的类型转换
变量、interface{} 和reflect.Value是可以相互转换的
四、使用反射操作基本数据类型
package main
import (
"fmt"
"reflect"
)
//定义一个函数
func test(re interface{}) {
//使用反射获取类型
rType := reflect.TypeOf(re)
fmt.Println("rType:",rType)
//使用反射获取值
rVal := reflect.ValueOf(re)
fmt.Println("rVal:",rVal)
//rVal的值没法直接使用,需要转换
num := 10 + rVal.Int()
fmt.Println("num:",num)
//将rval转化接口
iV := rVal.Interface()
//将iV转换为需要的类型
i := iV.(int)
num2 := 10+ i
fmt.Println("num:",num2)
}
func main() {
//定义一个基本数据类型
i := 10
test(i)
}
使用反射操作结构体
package main
import (
"fmt"
"reflect"
)
//定义一个结构体
type Student struct {
Name string
Age int
}
//定义一个函数
func test01(re interface{}) {
//使用反射获取类型
rType := reflect.TypeOf(re)
fmt.Println("rType:",rType)
//使用反射获取值
rVal := reflect.ValueOf(re)
fmt.Println("rVal:",rVal)
//这里需要转换
iV := rVal.Interface()
student, ok :=iV.(Student)
if !ok {
fmt.Println("转换失败")
}
fmt.Println(student.Name)
}
func main() {
student := Student{"小明",20}
test01(student)
}
五、使用反射修改值
package main
import (
"fmt"
"reflect"
)
type Jack struct {
Name string
}
func main() {
var a int = 100
//获取反射对象
v := reflect.ValueOf(&a)
//取出地址
v = v.Elem()
v.SetInt(1)
fmt.Println("v的值为",v)
//修改结构体的值
jack := &Jack{}
j := reflect.ValueOf(jack)
j = j.Elem()
//获取结构体的字段
name := j.FieldByName("Name")
//修改结构体字段的值
name.SetString("小明")
fmt.Println("修改后的Name值为:",name.String())
}
六、使用反射创建实例
package main
import (
"fmt"
"reflect"
)
type Cat struct {
Name string
}
func main() {
//使用反射创建实例
var a int = 10
v := reflect.TypeOf(a)
value := reflect.New(v)
fmt.Println("value的类型为:",value.Type())
fmt.Println("value的类别为:",value.Kind())
cat := Cat{
Name: "小花",
}
c := reflect.TypeOf(cat)
C := reflect.New(c)
fmt.Println("C的类型为:",C.Type())
fmt.Println("C的类别为:",C.Kind())
}
七、使用反射便利结构体方法
package main
import (
"fmt"
"reflect"
)
//定义一个结构体
type Animal struct {
}
func (a Animal) Area() string {
return "area方法调用"
}
func (a Animal) GetArea()string {
return "GetArea方法被调用"
}
func showList(x interface{}) {
v := reflect.ValueOf(x)
t := v.Type()
fmt.Println("t类型为",t)
for i := 0; i < v.NumMethod(); i++ {
method := v.Method(i)
fmt.Println(t.Method(i))
fmt.Println("方法名为:",t.Method(i).Name)
fmt.Println(method.String())
}
}
func main() {
animal := Animal{}
showList(animal)
}
八、练习
给你-一个变量var v float64= 1.2,请使用反射来得到它的reflect.Value,然后获取对应的Type, Kind和值,并将reflect.Value转换成interface{} , 再将interface{}转换成float64。
package main
import (
"fmt"
"reflect"
)
//
func rtest01(v float64) {
//获取ValueOf的值
rV := reflect.ValueOf(v)
fmt.Println(rV)
//获取Kind的值
i := rV.Kind()
//获取Type的值
i2 := rV.Type()
fmt.Println("i=",i)
fmt.Println("i2=",i2)
//转换为接口
iV := rV.Interface()
f := iV.(float64)
fmt.Println(f)
}
func main() {
var v float64 = 1.2
rtest01(v)
}
版权声明:本文为qq_46093575原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。