为了避免过多的意大利面条式代码,我想按名称设置 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 新手”的我)在这种情况下必须做什么才能使其工作。
最佳答案
您需要将指向o
的指针传递给reflect.ValueOf
。通过简单地传递值,结构的字段将不可寻址。
r := reflect.ValueOf(&o)
f := reflect.Indirect(r).FieldByName("Uid")
f.SetUint(42)
但是,如果可能的话,我会不假思索地尝试实现它。在您的 Protocol Buffer 定义中使用映射,或在您的 Go 代码中使用开关:
switch name {
case "Uid":
o.Uid = uintValue
case "Name"
o.Name = stringValue
}
非反射代码不太可能在运行时失败。
关于go - 按名称设置 protobuf 属性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49982976/