文章目录

  • 前言
  • 内容
    • Oneof
    • Using Oneof
    • Oneof Features
    • Backwards-compatibility issues

前言

工作需要,需要用到 protobuf3 中的 oneof 来定义数据结构,在这里翻译一下 pb官方文档,oneof。
(意译+机翻,塑料英语勿喷,欢迎指正)

内容

Oneof

If you have a message with many fields and where at most one field will be set at the same time, you can enforce this behavior and save memory by using the oneof feature.
如果你有一个 message 且里面有很多字段,但对于每个 message,你只会为至多一个字段赋值,那么这时候你就可以用 oneof 来强制遵循这种行为(为至多一个字段赋值)同时起到节省内存空间的效果。

Oneof fields are like regular fields except all the fields in a oneof share memory, and at most one field can be set at the same time. Setting any member of the oneof automatically clears all the other members. You can check which value in a oneof is set (if any) using a special case() or WhichOneof() method, depending on your chosen language.
除了 oneof 中所有字段共享内存并且最多只可以同时设置一个字段外,oneof 字段跟常规字段没有太大区别。设置 oneof 的任何成员都会自动清除所有其他成员。你可以通过使用 case() 或者 WhichOneof() 来确认 oneof 设置了哪个字段,用哪种方法取决于你使用的编程语言。

Using Oneof

To define a oneof in your .proto you use the oneof keyword followed by your oneof name, in this case test_oneof:
要在 .proto 文件中定义 oneof,你需要使用 oneof 关键字,后面跟着 oneof 字段的名称,就像本例 test_oneof

message SampleMessage {oneof test_oneof {string name = 4;SubMessage sub_message = 9;}
}

You then add your oneof fields to the oneof definition. You can add fields of any type, except map fields and repeated fields.( If you need to add a repeated field to a oneof, you can use a message containing the repeated field. 【protobuf2】)
然后,你可以将字段添加到 oneof 中。 你可以添加任何类型的字段,map 字段和 repeated 字段除外。

In your generated code, oneof fields have the same getters and setters as regular fields. You also get a special method for checking which value (if any) in the oneof is set. You can find out more about the oneof API for your chosen language in the relevant API reference.
在你写的代码中,oneof 字段具有跟常规字段相同的 getter 和 setter。你还可以获得一种特殊的方法来确认 oneof 设置了哪个值(如果有的话)。你可以在相关文档中找到有关所选语言的 oneof API 的更多信息。

Oneof Features

Setting a oneof field will automatically clear all other members of the oneof. So if you set several oneof fields, only the last field you set will still have a value.
设置一个 oneof 的成员都会自动清除所有其他成员,所以如果你多次设置 oneof 的成员,泽只有最后一次设置的成员有值

SampleMessage message;
message.set_name("name");
CHECK(message.has_name());
message.mutable_sub_message();   // Will clear name field.
CHECK(!message.has_name());

If the parser encounters multiple members of the same oneof on the wire, only the last member seen is used in the parsed message.
如果解析器在线路上遇到同一个 oneof 的多个成员,则在解析的消息中只使用最后一个看到的成员。

A oneof cannot be repeated.
oneof 不能重复

Reflection APIs work for oneof fields.
反射 API 适用于 oneof 字段。

If you set a oneof field to the default value (such as setting an int32 oneof field to 0), the “case” of that oneof field will be set, and the value will be serialized on the wire.
如果将 oneof 字段设置为默认值(例如将 int32 oneof 字段设置为 0),则会设置该 oneof 字段的“大小写”,并且该值将在线上序列化。

If you’re using C++, make sure your code doesn’t cause memory crashes. The following sample code will crash because sub_message was already deleted by calling the set_name() method.
如果您使用 C++,请确保您的代码不会导致内存崩溃。 以下示例代码将崩溃,因为 sub_message 已通过调用 set_name() 方法删除。

SampleMessage message;
SubMessage* sub_message = message.mutable_sub_message();
message.set_name("name");      // Will delete sub_message
sub_message->set_...            // Crashes here

Again in C++, if you Swap() two messages with oneofs, each message will end up with the other’s oneof case: in the example below, msg1 will have a sub_message and msg2 will have a name.
同样在 C++ 中,如果您使用 oneofs Swap() 两条消息,则每条消息都会以另一个的 oneof 情况结束:在下面的示例中,msg1 将有一个 sub_message,而 msg2 将有一个 name。

SampleMessage msg1;
msg1.set_name("name");
SampleMessage msg2;
msg2.mutable_sub_message();
msg1.swap(&msg2);
CHECK(msg1.has_sub_message());
CHECK(msg2.has_name());

Backwards-compatibility issues

向后兼容性问题

Be careful when adding or removing oneof fields. If checking the value of a oneof returns None/NOT_SET, it could mean that the oneof has not been set or it has been set to a field in a different version of the oneof. There is no way to tell the difference, since there’s no way to know if an unknown field on the wire is a member of the oneof.
添加或删除其中一个字段时要小心。 如果检查 oneof 的值返回 None/NOT_SET,则可能意味着 oneof 尚未设置或已设置为 oneof 不同版本中的字段。 没有办法区分,因为无法知道线路上的未知字段是否是 oneof 的成员。

Tag Reuse Issues
标签重用问题
Move fields into or out of a oneof: You may lose some of your information (some fields will be cleared) after the message is serialized and parsed. However, you can safely move a single field into a new oneof and may be able to move multiple fields if it is known that only one is ever set.
将字段移入或移出 oneof:在消息被序列化和解析后,您可能会丢失一些信息(某些字段将被清除)。 但是,您可以安全地将单个字段移动到新的 oneof 中,并且如果知道只设置了一个字段,则可以移动多个字段。

Delete a oneof field and add it back: This may clear your currently set oneof field after the message is serialized and parsed.
删除 oneof 字段并重新添加:这可能会在消息被序列化和解析后清除您当前设置的 oneof 字段。

Split or merge oneof: This has similar issues to moving regular fields.
拆分或合并其中一个:这与移动常规字段有类似的问题。

protobuf3 oneof相关推荐

  1. protobuf3 自定义option_Protobuf3 语法指南

    以前我翻译了 Protobuf2 语法指南,现在 千念飞羽把protobuf3的语法指南也翻译了,我也转载一下,读者可以有个参考. 译文地址是: Protobuf3语言指南. 英文原文: Langua ...

  2. ProtoBuf3语法指南(Protocol Buffers)_下

    0.说明 ProtoBuf3语法指南, 又称为proto3, 是谷歌的Protocol Buffers第3个版本. 本文基于官方英文版本翻译, 加上了自己的理解少量修改, 一共分为上下两部分. 1.A ...

  3. protobuf3 自定义option_ProtoBuf3语法指南(Protocol Buffers)_下

    0.说明 ProtoBuf3语法指南, 又称为proto3, 是谷歌的Protocol Buffers第3个版本. 本文基于官方英文版本翻译, 加上了自己的理解少量修改, 一共分为上下两部分. 1.A ...

  4. Protobuf3 使用、入门教程及Demo

    文章目录 Protobuf简介 用法: 更复杂的demo oneof Protobuf简介 ​ 简单设计协议, 通过自带工具转换成为对应的语言代码, 协议是二进制协议, 设计时只需要描述各个类的关系, ...

  5. Protobuf3语言指南

    参考文章:http://blog.csdn.net/u011518120/article/details/54604615 英文原文:  Language Guide (proto3)  中文出处:  ...

  6. 编译protobuf-3.11.4 错误: aclocal-1.15: command not found的解决办法

    操作系统:kylinV10 protobuf版本:3.11.4 当编译protobuf时,执行以下命令: ./configure --prefix=$LEAN/protobuf3.11.4 出现以下错 ...

  7. Protobuf3教程

    Protobuf3教程 https://blog.csdn.net/hulinku/article/details/80827018 Protobuf语言指南--.proto文件语法详解 https: ...

  8. ProtoBuf3语法指南(Protocol Buffers)_上

    0.说明 ProtoBuf3语法指南, 又称为proto3, 是谷歌的Protocol Buffers第3个版本. 本文基于官方英文版本翻译, 加上了自己的理解少量修改, 一共分为上下两部分. 1.序 ...

  9. protobuf3 自定义option_Protobuf3语法详解

    定义一个消息类型 先来看一个非常简单的例子.假设你想定义一个"搜索请求"的消息格式,每一个请求含有一个查询字符串.你感兴趣的查询结果所在的页数,以及每一页多少条查询结果.可以采用如 ...

  10. Unity中使用Protobuf3.0

    今天准备在unity中使用protobuf, 但是遇到了一些问题,记录一下. 首先,我们到google protobuf github 上下载工程,主要有两个东西: 1.Protocol Compil ...

最新文章

  1. CentOS各版本ISO下载地址
  2. .so文件反编译_o泡果奶软件在哪下载 o泡果奶一份礼物魔性文件下载
  3. android mmkv使用_MMKV解读
  4. 对高性能Web服务的研究笔记
  5. mysql和sql互导_Mysql和SqlServer互相转换
  6. Subversion Server For Windows安装指南
  7. sklearn自学指南(part16)--SGD,Perceptron,PassiveAggressive
  8. 从pg_hba.conf文件谈谈postgresql的连接认证
  9. 关于阈值化函数cvThreshold()
  10. android adb端口被占用问题
  11. 千万不能错过的Android NDK下载安装及配置
  12. mysql 5.7.26卸载_MySQL 5.7.26安装与卸载
  13. python窗口居中_Tkinter窗口在屏幕居中的问题
  14. EAS收集KSQL日志的方法
  15. Android自定义View实现三角到八角的属性分布图-雷达图(蜘蛛网图)
  16. IBM服务器诊断面板LED指示灯详细介绍
  17. 笔记本外接显示器卡顿解决方案
  18. 一款好用的网络骗子举报系统无加密版本源码
  19. 反卷积原理和实际代码详细讲解!
  20. 微型计算机具有推理能力吗,以下的计算机类型中,(  )不属于微型计算机

热门文章

  1. java安卓开发改变图片大小_Android代码中动态设置图片的大小(自动缩放),位置...
  2. Quartus ii 13.1 数字时钟
  3. 机器人动力学建模之理解惯性张量
  4. 如何关闭正在运行的端口
  5. Fragment、FragmentActivity、Fragment生命周期及Fragment组件穿透
  6. LR证书过期解决办法
  7. iPhone开发阶段性总结
  8. 微信小程序---详情页
  9. 一文盘点目前免费的云服务器
  10. 综述 | 一文看尽三种针对人工智能系统的攻击技术及防御策略