一、反射是什么?反射的主要应用场景
1.Golang提供了一种机制,在编译时不知道类型的情况下,可更新变量、运行时查看值、调用方法以及直接对他们的布局进行操作的机制,称为反射
2.反射应用场景
a)有时你需要编写一个函数,但是并不知道传给你的参数类型是什么,可能是没约定好;也可能是传入的类型很多,这些类型并不能统一表示。这时反射就会用的上了。
b)有时候需要根据某些条件决定调用哪个函数,比如根据用户的输入来决定。这时就需要对函数和函数的参数进行反射,在运行期间动态地执行函数。
3.反射主要与Golang的interface类型相关,只有interface类型才有反射一说
二、反射reflect包主要方法
1.reflect.Type和reflect.Value
reflect提供了两种类型来进行访问接口变量的内容:
1)reflect.ValueOf()获取输入参数接口中的数据的值,如果为空则返回0
2)reflect.TypeOf()动态获取输入参数接口中的值的类型,如果为空则返回nil
3)reflect.Type和reflect.Value的关系
在go语言中,每个值都包含两个内容:类型和实际的值。从类型角度来看,reflect.Value是一个关于的二元组,而reflect.Type是值的类型,二者是包含关系。从方法角度来看,reflect.TypeOf 和 (reflect.ValueOf(x)).Type都可以返回reflect.Type;(reflect.ValueOf(x)).Float可以返回实际的值(类似的方法还包括(reflect.ValueOf(x)).Int、(reflect.ValueOf(x)).Bool等);(reflect.ValueOf(x)).Kind可以返回一个常量定义的类型。
2.reflect.Type和Value的常用方法
1)Type和Value拥有的同名方法
2)Type中独有的方法
3)Value中独有的方法
三、反射示例
1.通过反射修改内容
package main
import (
"reflect"
"fmt"
)
type Language struct {
Name string
}
func main() {
s := &Language{Name: “go”}
v := reflect.ValueOf(s)
// 修改值必须是指针类型
if v.Kind() != reflect.Ptr {
fmt.Println(“not pointer type”)
return
}
// 获取指针所指向的元素
v = v.Elem()
// 获取目标key的Value的封装
name := v.FieldByName("Name")
if name.Kind() == reflect.String {
name.SetString(“python”)
}
fmt.Printf("%#v