【问题标题】:Modify null pointer field in struct through reflection in Go通过 Go 中的反射修改 struct 中的空指针字段
【发布时间】:2019-07-02 19:25:06
【问题描述】:

我正在尝试通过反射循环修改空指针字段“MyField”的间接值。 我感到恐慌:reflect: 调用 reflect.Value.Set 为零值。

有什么想法吗?

https://play.golang.org/p/IJvA_J_cD60

package main

import (
    "fmt"
    "reflect"
)

type MyStruct struct {
    MyField *string
}

func main() {
    s := MyStruct{}

    v := reflect.ValueOf(s)

    for i := 0; i < v.NumField(); i++ {
        valueField := v.Field(i)
        fieldName := v.Type().Field(i).Name
        if fieldName == "MyField" && valueField.Kind() == reflect.Ptr {
            valueField.Elem().Set(reflect.ValueOf("some changed name"))
            fmt.Printf("the elem after change: %v\n", valueField.Elem())
        }

    }
    fmt.Print(*s.MyField)
}

非常感谢!

【问题讨论】:

    标签: pointers go reflection null


    【解决方案1】:

    该程序有两个问题。

    无法设置该字段,因为v 不是可寻址值。要获取可寻址值,请从指向 s 的指针创建 reflect.Value:

    s := MyStruct{}
    v := reflect.ValueOf(&s).Elem()
    

    程序试图通过一个 nil 指针来设置一个值。反射代码与*s.MyField = "some changed name" 相同。如果问题中的 MyField 为 nil,则此语句将出现恐慌。要解决此问题,请在字段中设置一个指针:

    t := "some changed name"
    valueField.Set(reflect.ValueOf(&t))
    

    Run it on the Playground

    【讨论】:

    • 非常感谢!在这种情况下,我知道字段类型。如果我想用指向类型的空/零值(即本例中的空字符串)初始化字段怎么办?对此有什么想法吗?
    • valueField.Set(reflect.New(valueField.Type().Elem()))
    猜你喜欢
    • 1970-01-01
    • 2023-03-08
    • 2021-01-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-04-16
    • 1970-01-01
    相关资源
    最近更新 更多