【问题标题】:How can we put a variant message ( one of a few message types ) inside a protobuf message?我们如何将变体消息(几种消息类型之一)放入 protobuf 消息中?
【发布时间】:2014-01-07 11:47:39
【问题描述】:

我们如何将变体消息(几种消息类型之一)放入 protobuf 消息中?

message typeA {
    ....
}

message typeB {
    ....
}

message typeC {
    [typeB|typeA] payload;
}

【问题讨论】:

    标签: protocol-buffers


    【解决方案1】:

    你需要这样做:

    message TypeC {
      optional TypeA a = 1;
      optional TypeB b = 2;
    }
    

    如果有很多变体,您可能还想添加一个标签字段,这样您就不必为每个变体检查has_*()

    Protobuf 文档对此进行了介绍:https://developers.google.com/protocol-buffers/docs/techniques#union

    PS。 Protobufs 缺少的这个功能在Cap'n Proto 中得到了修复,这是同一作者(我)的一个新的序列化系统:Cap'n Proto 为此目的实现了"unions"。在离开 Google 之前,我还在 Protobufs 中实现了联合,但在我离开之前没有设法将我的更改合并到主线中。对不起。 :(

    编辑:看起来 Protobuf 团队最终合并了我的更改并发布了 2.6.0 版。 :) 见the oneof declaration

    【讨论】:

    • 感谢创建oneof,你摇滚!
    【解决方案2】:

    查看 2.6 版中的新 oneof 功能:https://developers.google.com/protocol-buffers/docs/reference/java-generated#oneof

    您现在可以执行以下操作:

    message TypeC {
        oneof oneof_name {
            TypeA a = 1;
            TypeB b = 2;
        }
    }
    

    同一个oneof中的字段会共享内存,同时只能设置一个字段。

    【讨论】:

    • 如何查看设置的是哪一个?我有int、string、boolean等,那么如何判断填的是哪一个呢?
    • 目前我正在使用下面的测试,但 protobuffer 可能有更优雅的东西:!Proto.GetData.getDefaultInstance().equals(all.getGetData());
    • 另一种方法是切换all.getMessageCase()时出现的字符串值
    • 如果 TypeA 和/或 TypeB 有一个可重复的成员,这仍然有效吗?
    • @ChrisMcCowan 不幸的是,oneof 不允许重复字段
    猜你喜欢
    • 2021-09-10
    • 1970-01-01
    • 1970-01-01
    • 2019-09-04
    • 2013-04-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多