猿问

通过反射调用结构体方法

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


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)

}

我希望的是在我打印方法的地方获取我的解析方法并对其运行 .Call() 。相反,它打印出来:<invalid reflect.Value>我不能反对。


我想我很难理解每个方法的返回值。我知道我必须使用 ValueOf 来提取值,但似乎我尝试的任何排列都是从反射类本身获取方法:-p叹息


元芳怎么了
浏览 131回答 1
1回答

繁花如伊

问题在于该方法位于指针接收器上,但该函数正在与赋值器接收器一起使用。重写该函数以使用指向结构的指针:func setPropertiesFromFlags(vp reflect.Value, viper *viper.Viper) {&nbsp; &nbsp; method := vp.MethodByName("Parse")&nbsp; &nbsp; fmt.Println(method)&nbsp; &nbsp; v := vp.Elem()&nbsp; &nbsp; t := v.Type()&nbsp; &nbsp; for i := 0; i < t.NumField(); i++ {&nbsp; &nbsp; &nbsp; &nbsp; field := t.Field(i)&nbsp; &nbsp; &nbsp; &nbsp; switch field.Type.Kind() {&nbsp; &nbsp; &nbsp; &nbsp; case reflect.Struct:&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; setPropertiesFromFlags(v.Field(i).Addr(), viper) // <-- take address of field here&nbsp; &nbsp; &nbsp; &nbsp; case reflect.String:&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; v.Field(i).SetString(viper.GetString(field.Tag.Get("name")))&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; }}像这样调用:&nbsp; &nbsp;setPropertiesFromFlags(reflect.ValueOf(c), viper) // <-- do not call Elem()
随时随地看视频慕课网APP

相关分类

Go
我要回答