go - 用反射调用struct方法

标签 go reflection

我在递归反射函数中调用方法时遇到麻烦。这里是:

func setPropertiesFromFlags(v reflect.Value, viper *viper.Viper) {
    t := v.Type()
    method := v.MethodByName("Parse")
    fmt.Println(method)
    for i := 0; i < t.NumField(); i++ {
        field := t.Field(i)
        switch field.Type.Kind() {
        case reflect.Struct:
            setPropertiesFromFlags(v.Field(i), viper)
        case reflect.String:
            v.Field(i).SetString(viper.GetString(field.Tag.Get("name")))
    }
}

我用以下方法调用该函数:
// Config struct passed to all services
type Config struct {
    common.Config
    common.ServerConfig
    common.AuthConfig
}
// Parse the thing already!
func (c *Config) Parse() {
    fmt.Println("RUN THIS THING")
}
int main() {
   setPropertiesFromFlags(reflect.ValueOf(c).Elem(), viper)
}

我希望在我打印方法的地方得到我的parse方法,然后对它运行.Call()。相反,它正在打印出来:<invalid reflect.Value>,我无法对其进行调用。

我想我无法将每个方法的返回值都放在头上。我知道我必须使用ValueOf来提取值,但是似乎我尝试从反射类本身获取方法的任何排列:-p感叹

最佳答案

问题在于该方法在指针接收器上,但是该函数正在与赋值器接收器一起使用。
重写该函数以使用指向结构的指针:

func setPropertiesFromFlags(vp reflect.Value, viper *viper.Viper) {
    method := vp.MethodByName("Parse")
    fmt.Println(method)

    v := vp.Elem()
    t := v.Type()
    for i := 0; i < t.NumField(); i++ {
        field := t.Field(i)
        switch field.Type.Kind() {
        case reflect.Struct:
            setPropertiesFromFlags(v.Field(i).Addr(), viper) // <-- take address of field here
        case reflect.String:
            v.Field(i).SetString(viper.GetString(field.Tag.Get("name")))
        }
    }
}

像这样打电话:
   setPropertiesFromFlags(reflect.ValueOf(c), viper) // <-- do not call Elem()

关于go - 用反射调用struct方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58736651/

相关文章:

c# - 比较使用 PropertyInfo.GetValue() 检索的值时出现意外结果

go - Go 中的可变泛型参数

java - ReflectionUtils 如何替换已弃用的方法?

c# - 如何根据表名在 DbContext 中选择正确的 DbSet

reflection - 如何在 kotlin 中通过反射设置委托(delegate)属性值?

java - 类无法使用来自不同包的反射访问其自己的 protected 成员变量

file - 如何使用 Go 字节有效地替换两个字符串分隔符之间出现的字符串?

syntax - 为什么Go中给变量赋值有等号

go - 给定一个任意字符串,我怎样才能将命令输出到 bash?

mongodb - 将UpdateOne与MongoDB Golang驱动程序一起使用时Upsert无法正常工作