通过名称设置protobuf属性

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.