我在递归反射函数中调用方法时遇到麻烦。这里是:
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>我不能反对。
<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()