Go 通過反射的reflect設定實際變數的值

LiberHome發表於2022-06-04

這篇部落格的目的是介紹如何用反射物件修改時間變數的值。要達到上述目的,最基本的操作如下:

基本資料型別的修改

package main

import (
    "fmt"
    "reflect"
)

func main() {
    var num float64 = 3.14
    fmt.Println("num is : ", num)
    //下面操作指標獲取num地址,記得加上&取地址
    pointer := reflect.ValueOf(&num)
    newValue := pointer.Elem()

    fmt.Println("type: ", newValue.Type())
    fmt.Println("can set or not:", newValue.CanSet())

    //重新賦值
    newValue.SetFloat(6.28)
    fmt.Println(num)
}

執行結果如下:

num is :  3.14
type:  float64
can set or not: true
6.28

結構體內的數值修改

本質和上面一樣還是運算元值對應的指標地址。
先看一下怎麼獲取相感應的值,程式碼如下:

package main

import "fmt"

type Student struct {
    Name   string
    Age    int
    School string
}

func main() {
    s1 := Student{"shilingfly", 18, "TsingHua"}
    fmt.Printf("%T\n", s1)
    p1 := &s1
    fmt.Println(p1.Name)
}

執行結果如下:

main.Student
shilingfly

然後看一下,如何修改相應欄位的值,程式碼如下:

package main

import (
    "fmt"
    "reflect"
)

type Student struct {
    Name   string
    Age    int
    School string
}

func main() {
    s1 := Student{"shilingfly", 18, "TsingHua"}
    fmt.Printf("%T\n", s1)
    p1 := &s1
    fmt.Println(p1.Name)
    //改變數值
    value := reflect.ValueOf(&s1)
    //看一下是不是reflect的指標型別
    if value.Kind() == reflect.Ptr {
        newValue := value.Elem()
        fmt.Println("can set or not: ", newValue.CanSet())

        //在這裡一項一項的修改
        f1 := newValue.FieldByName("Name")
        f1.SetString("Lisome")
        f2 := newValue.FieldByName("Age")
        f2.SetInt(17)
        f3 := newValue.FieldByName("School")
        f3.SetString("MIT")
        fmt.Println(s1)
    }
}

執行結果如下:

main.Student
shilingfly
can set or not:  true
{Lisome 17 MIT}

參考:bilibili

相關文章