1.1.1. 一、通过反射修改变量值。
1、通过反射修改基本类型的变量值。
核心代码是refValue.Elem().SetInt(700)
。
func main() {
var num int = 89
refValue := reflect.ValueOf(&num)
fmt.Println("Kind =",refValue.Kind()) //Kind = ptr 表示指针类型
//改变原始变量 num 的值
refValue.Elem().SetInt(700)
fmt.Println(num) // 700
}
说明:
1、
refValue := reflect.ValueOf(&num)
这里要传递变量num的地址。如果不传递地址,下面的代码
refValue.Elem().SetInt(700)
会panic。2、
refValue.Elem().SetInt(700)
修改值的时候,需要refValue.Elem()
得到反射对应的原始变量num。具体看文档。
2、使用反射修改struct类型的变量。
核心代码是rval.Elem().FieldByName("Age").SetInt(26)
修改Age属性的值。
// Student结构体
type Student struct {
Name string `json:"nmae"`
Age int `json:"age"`
}
func main() {
stu := Student{
Name:"张三",
Age:18,
}
rval := reflect.ValueOf(&stu) // 获取 reflect.Value
rval.Elem().FieldByName("Age").SetInt(26)
fmt.Println(stu.Age) //26
}
1.1.2. 二、使用反射,获取结构体字段,调用结构体方法。
- 结构体内容:
// Student结构体
type Student struct {
Name string `json:"nmae"`
Age int `json:"age"`
}
func (stu Student) Sub(num1 int, num2 int) int {
fmt.Println("执行 Sub()......",num1,num2)
return stu.Age - num1 - num2
}
func (stu Student) Add() int {
fmt.Println("执行 Add()......")
return stu.Age
}
- 使用反射,获取结构体字段,调用结构体方法。
// 反射
func refTest(s Student) {
rtype := reflect.TypeOf(s) //获取 reflect.Type
rval := reflect.ValueOf(s) // 获取 reflect.Value
kd := rval.Kind()
if kd != reflect.Struct{
fmt.Println("不是 Struct 类型")
return
}
numField := rval.NumField() // 有多少字段
fmt.Println("结构体的字段个数 =",numField)// 结构体的字段个数 = 2
/*字段的获取*/
for i := 0; i < numField; i++ {
fmt.Printf("字段 %d 的值=%v \n",i,rval.Field(i)) // 字段 1 的值=18
tag := rtype.Field(i).Tag //获取tag
fmt.Println(tag) // json:"nmae"
//tag.Get("json") 获取tag的某个key
fmt.Println(tag.Get("json")) //nmae
}
/*方法*/
fmt.Println("---------------------------")
numOfMethod := rval.NumMethod()// 有多少方法
fmt.Println("结构体的方法个数 =",numOfMethod)// 结构体的方法个数 = 2
// 调用第 0 个方法( 方法的排序按照方法名的字母排序,所以第0个方法是Add )
rval.Method(0).Call(nil) // 执行 Add()......
//params := make([]reflect.Value,2)
var params []reflect.Value
params = append(params, reflect.ValueOf(15), reflect.ValueOf(22))
var result []reflect.Value = rval.Method(1).Call(params) // 执行 Sub()...... 15 22
fmt.Println("方法执行结果 =",result[0]) // 方法执行结果 = -19
}
func main() {
stu := Student{
Name:"张三",
Age:18,
}
refTest(stu)
}
- 执行结果:
结构体的字段个数 = 2
字段 0 的值=张三
json:"nmae"
nmae
字段 1 的值=18
json:"age"
age
---------------------------
结构体的方法个数 = 2
执行 Add()......
执行 Sub()...... 15 22
方法执行结果 = -19