go - 按名称设置 protobuf 属性

标签 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 新手”的我)在这种情况下必须做什么才能使其工作。

最佳答案

您需要将指向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/

相关文章:

mysql - Golang - 从 MySQL 检索多个结果,然后将它们显示为 JSON

hadoop - Hbase 问题 |反序列化 SCAN 字符串时出现谷歌 protobuf 标签不匹配错误

java - 从这个 .proto 文件生成代码后,这个特定的函数是如何产生的?

c# - thrift 在反序列化并再次序列化时是否保留未知字段/字节?

go - 如何在 Go 中创建一个通用的 GRPC 服务器启动函数

go - 当我在地址中使用端口时,Kubernetes 日志不打印请求输出

arrays - 如何将元素添加到 slice 反射?

go - 什么时候释放长时间运行的 Go 程序中的资源?

c# - Protocol Buffer#3 将消息从 c++ 发送到 c#

c++ - 如何根据谷歌 Protocol Buffer 的要求定义重复字段?