Let's say I have a base struct that's a composite of two others:
type Config struct {
common.Config
common.ServerConfig
APIPath string `type:"string" name:"apipath" default:"localhost:8443" desc:"Path to the gRPC API server"`
ServePath string `type:"string" name:"servepath" default:"/" desc:"Path to serve the API from"`
Organization string `type:"string" name:"organization" default:"" desc:"Default organization name"`
}
I'd like to iterate through every field in the struct and pull values into the struct:
func NewConfig(c Configer) {
setConfigFlags(reflect.TypeOf(c).Elem(), c.GetViper())
}
So I'd call it so:
conf := Config{}
common.NewConfig(&conf)
My setConfigFlags is doing some recursion:
func setConfigFlags(t reflect.Type, viper *viper.Viper) {
for i := 0; i < t.NumField(); i++ {
field := t.Field(i)
switch field.Type.Kind() {
case reflect.Struct:
setConfigFlags(field.Type, viper)
continue
case reflect.String:
fieldValue := reflect.ValueOf(&field).Elem()
if !fieldValue.IsValid() || !fieldValue.CanSet() {
return
}
fieldValue.SetString(
viper.GetString(field.Tag.Get("name")),
)
}
}
}
Now once I hit the SetString line towards the bottom I'm getting this error:
panic: reflect: call of reflect.Value.SetString on struct Value
When I look at the type of fieldValue at that point it's a structfield. I'm having trouble trying to address the value and change the value of the field. I believe I'm not grabbing the address of the actual struct field properly. The examples and documentation surely isn't helping.
In this particular example I'm pulling viper values. Basically looking for a way to define my viper definitions via struct tags, that's the ultimately goal.
reflect.TypeOf(c).Elem()... You're passing in the type ofcnot its value, you won't be able to set anything to a type.reflect.Typeas the argument to your set config func is the first problem, it should bereflect.Valueand it should be addressable. - mkopriva