Good afternoon, I try to deal with reflection and tags in the structures in Go, using the configuration example for the application.
There is a code:
package main import ( "fmt" "os" "reflect" "flag" ) type AppConfig struct { Pg string `cli:"pg" env:"PG" default:"host=host.local dbname=db user=user password=password" description:"Connection to PostgreSQL"` Redis string `cli:"redis" env:"REDIS" default:"host.local" description:"Redis server"` } func main() { config := GetConfig(&AppConfig{}) fmt.Println(config) } func GetConfig(config *AppConfig) *AppConfig { ref := reflect.TypeOf(*config) value := reflect.ValueOf(*config) for i := 0; i < value.NumField(); i++ { field := ref.Field(i) name := field.Tag.Get("env") if name != "" { env := os.Getenv(name) if env != "" { value.Field(i).SetString(env) } else { def := field.Tag.Get("default") if def != "" { value.Field(i).SetString(def) } } } /* cli := field.Tag.Get("cli") if cli != "" { flag.StringVar((*string)(value.Field(i).Pointer()), cli, value.Field(i).String(), field.Tag.Get("description")) } */ } flag.Parse() return config } Sandbox: https://play.golang.org/p/b7bDUd-mj- I get
panic: reflect: reflect.Value.SetString using unaddressable value I feel that something is missing, but what?
PS In the commented section, work with command-line flags, but here my understanding of what is happening there is not enough