Reputation: 1940
I have a struct of pointers to various primitives. The struct is a config for an application and the reason the fields are pointers is so I can determine between a field set to the default and a field that hasn't been set at all - to enforce "required" fields.
Here is a simple example:
type Config struct {
A *string
B *int
C *bool
D *[]string // wildcard!
}
So I grab the reflect.Value
via reflect.ValueOf(*cfg)
which gives me a .Field
on each element, which I iterate through.
The thing is, each element doesn't pass CanAddr
or CanSet
, I can't seem to find a way to set the value held behind the pointer. Is this a limitation of the language? Will I need to make my fields non-pointers? That would suck as there would be no way to determine if a user specified an empty string or just didn't set it at all for example.
Oh and bonus points for setting/appending a []string field! That one confused me even without pointers thrown in the mix!
Upvotes: 0
Views: 3881
Reputation: 121129
Replace these lines:
t := reflect.TypeOf(*cfg)
v := reflect.ValueOf(*cfg)
with
v := reflect.ValueOf(cfg).Elem()
t := v.Type()
to get an addressable value.
The value created by reflect.ValueOf(*cfg)
has no reference to addressable memory. The fix is to dereference the pointer in the reflect domain.
Regarding the []string. Because there's a difference between a null slice and an empty slice, there may be no need to use *[]string. In any case, use the reflect.Append function to append to a slice:
var s []string
v := reflect.ValueOf(&s).Elem()
v.Set(reflect.Append(v, reflect.ValueOf("hello")))
v.Set(reflect.Append(v, reflect.ValueOf("world")))
fmt.Println(s) // prints [hello world]
Upvotes: 2