按名称设置protobuf属性

时间:2018-04-23 13:55:55

标签: go protocol-buffers

为避免过多的意大利面风格代码,我想按名称设置 golang protobuf对象的某些属性。因此,我们可以说某些.proto定义如

syntax = "proto3";
package foo;

message User {
    uint64 uid = 1;
    string name = 2;
}

和代码访问它

o := foo.User{Name: "John Doe"}
o.Uid = 40

存在。我希望能够在没有点缀符号的情况下设置Uid。反思构造如

r := reflect.ValueOf(o)
f := reflect.Indirect(r).FieldByName("Uid")
f.SetUint(42)

似乎失败了,因为Uid不是可寻址的。我发现了一些关于结构字段不可寻址的帖子,但它仍然不清楚(对我来说是一个" golang newbie")在这种情况下必须做什么让它发挥作用。

1 个答案:

答案 0 :(得分:1)

您需要将指针o传递给reflect.ValueOf。通过简单地传递值,结构的字段将不可寻址。

r := reflect.ValueOf(&o)
f := reflect.Indirect(r).FieldByName("Uid")
f.SetUint(42)

但是,如果可能的话,我会尝试在没有反思的情况下实现这一点。在协议缓冲区定义中使用映射,或在Go代码中使用开关:

switch name {
case "Uid":
    o.Uid = uintValue
case "Name"
    o.Name = stringValue
}

非反射代码在运行时不太可能失败。