To avoid too much spaghetti style code, I'd like to set certain properties of a golang protobuf object by name. So lets say there's some kind of .proto
definition like
syntax = "proto3";
package foo;
message User {
uint64 uid = 1;
string name = 2;
}
and code accessing it like
o := foo.User{Name: "John Doe"}
o.Uid = 40
exists. I'd like to be able to set Uid
without the dotted notation. Reflection constructs like
r := reflect.ValueOf(o)
f := reflect.Indirect(r).FieldByName("Uid")
f.SetUint(42)
seem to fail, because Uid
is not addressable. I found several posts about struct fields not being addressable, but it's still unclear (to me as a "golang newbie") what has to be done in this context to make it work.
You need to pass a pointer to o
to reflect.ValueOf
. By simply passing the value, the fields of the struct will not be addressable.
r := reflect.ValueOf(&o)
f := reflect.Indirect(r).FieldByName("Uid")
f.SetUint(42)
If at all possible, however, I would try to implement this without reflection. Either use a map in your protocol buffer definition, or a switch in your Go code:
switch name {
case "Uid":
o.Uid = uintValue
case "Name"
o.Name = stringValue
}
The non-reflect code is less likely to fail at runtime.