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

results matching ""

    No results matching ""