繁体   English   中英

GO:我如何使用 go 反射来设置结构指针的值

[英]GO: how can i use go reflect to set the value of pointer of struct

package main

import (
    "fmt"
    "reflect"
)

type Config struct {
    App *AppConfig
}

type AppConfig struct {
    Name string
}

func (a *AppConfig) Parse() {
    a.Name = "111"
}

var (
    config = &Config{
        App: &AppConfig{},
    }
)

func main() {

    v := reflect.ValueOf(*config)
    typeOf := reflect.TypeOf(*config)

    for i := 0; i < typeOf.NumField(); i++ {
        method := v.Field(i).MethodByName("Parse")
        method.Call([]reflect.Value{})
    }
    fmt.Println(config)
}

看看这个,可以成功运行

但是当我改变

var (
    config = &Config{
        App: &AppConfig{},
    }
)

var (
    config = &Config{}
)

它将失败并出现错误 #恐慌:运行时错误:无效 memory 地址或 nil 指针取消引用#

我怎样才能成功运行

var (
    config = &Config{}
)

给定f:= v.Field(i)其中f表示指针类型,您首先需要检查f表示的值是否不是nil ,在反射 package 中有一个方法。 如果你返回true ,即它nil ,那么,在你可以调用那个字段的方法之前,你需要初始化那个字段,这样它就不再是nil了。 f.Set(reflect.New(f.Type().Elem()))

而且您还需要确保faddressable ,为此,将指针传递给配置以反映,即*Config ,而不是Config

v := reflect.ValueOf(config).Elem()
typeOf := reflect.TypeOf(config).Elem()

for i := 0; i < typeOf.NumField(); i++ {
    f := v.Field(i)
    if f.Kind() == reflect.Ptr && f.IsNil() {
        f.Set(reflect.New(f.Type().Elem()))
    }
    method := f.MethodByName("Parse")
    method.Call([]reflect.Value{})
}
fmt.Println(config)
fmt.Println(config.App)

https://go.dev/play/p/DMRFS41NXFS

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM