簡體   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