Any

Any消息类型允许您将消息作为嵌入类型,而不需要它们 .proto定义。Any包含任意序列化的消息(字节),以及一个URL,该URL充当该消息的全局唯一标识符并解析为该消息的类型。要使用Any类型,你需要导入google/protobuf/any.proto

import "google/protobuf/any.proto";message ErrorStatus {string message = 1;repeated google.protobuf.Any details = 2;
}

指定消息类型的默认类型URL是type.googleapis.com/packagename.messagename.

不同的语言实现将支持运行时库助手以typesafe方式打包和解压缩ANY类型的值——例如,在Java中,任何类型都有特殊的pack()和unpack()访问器,而在C++中有PackFrom()UnpackTo()方法:

// Storing an arbitrary message type in Any.
NetworkErrorDetails details = ...;
ErrorStatus status;
status.add_details()->PackFrom(details);// Reading an arbitrary message from Any.
ErrorStatus status = ...;
for (const Any& detail : status.details()) {if (detail.Is<NetworkErrorDetails>()) {NetworkErrorDetails network_error;detail.UnpackTo(&network_error);... processing network_error ...}
}

Oneof

如果您有一条包含许多字段的消息,并且最多同时设置一个字段,您可以使用其中oneof功能来强制执行此行为并节省内存。

Oneof 字段类似于常规字段,除了Oneof共享内存的所有字段之外,最多可以同时设置一个字段。设置Oneof 的任何成员都会自动清除所有其他成员。您可以使用case()或WhichOneof()方法检查Oneof 中的哪个值被设置(如果有的话),具体取决于您选择的语言。

使用Oneof

在您的 .proto中定义一个oneof 关键字后跟着oneof 名称,在本例中为test_oneof:

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

然后将您的oneof字段添加到oneof定义中。您可以添加任何类型的字段,但不能使用重复字段。

在生成的代码中,oneof字段具有与常规字段相同的setter和getter方法。您还可以获得一种特殊的方法来检查中的哪个值(如果有的话)被设置。你可以在相关的API参考中找到更多关于你选择的语言的API。

Oneof功能

设置oneof字段将自动清除oneof字段的所有其他成员。因此,如果您设置了几个oneof字段,则只有最后一个字段仍然有值。

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

如果解析器遇到同一oneof的多个成员,则在解析的消息中只使用最后一个成员。
oneof不能重复。
反射APIs适用于oneof字段。

如果您正在使用C++,请确保代码不会导致内存崩溃。下面的示例代码将导致内存崩溃,因为它通过set_name()方法调用了已经删除掉的sub_message。

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

同样在C++中,如果你Swap()两条oneof消息,每条消息将以另一条的oneof结尾:在下面的示例中,msg1将有一条子消息,msg2将有一个名字。

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

向后兼容性问题

添加或删除oneof字段时要小心。如果检查oneof的值会返回None / NOT _ SET,这可能意味着其中一个没有被设置,或者它已经被设置为oneof的不同版本中的字段。没有办法区分这两者,因为没有办法知道线上的未知区域是否是oneof的成员。

标签重用问题

将字段移入或移出:在序列化和解析消息后,您可能会丢失一些信息(一些字段将被清除)。但是,您可以安全地将单个字段移动到新的字段中,如果已知只有一个字段被设置,您也可以移动多个字段。

删除一个字段并将其添加回去:这可能会在消息序列化和解析后清除当前设置的一个字段。

拆分或合并其中一个:这与移动常规字段有类似的问题。

Proto3 Any与Oneof(转载)相关推荐

  1. 初识Protobuf协议

    本文作为Protobuf入门学习的第一篇文章,将简单介绍Protobuf协议以及如何使用Protobuf来实现序列化与反序列化. 原文地址:https://mp.weixin.qq.com/s/QbL ...

  2. Protobuf学习入门(一)

      笔者最近在学习使用tensorflow/serving,其中有不少涉及Protobuf相关的内容,因此接触学习了Prorobuf,记录于此,希望能对读者有所启发.   本文作为Protobuf入门 ...

  3. Proto3使用指南

    这篇指南讲述如何使用Protocol Buffers来结构化你的Protocol Buffer数据,包括.proto文件语法以及如何从.proto文件生成你的访问类型.本文主要涵盖了proto3的语法 ...

  4. Protobuf 的 proto3 与 proto2 的区别

    Protobuf 的 proto3 与 proto2 的区别 转载自:https://solicomo.com/network-dev/protobuf-proto3-vs-proto2.html 这 ...

  5. gRPC学习记录(三)--proto3知识

    在上一篇中,得知proto文件是定义服务端和客户端通讯接口的标准,说白了就是客户端该传什么样的参数,服务端该返回什么样子的参数,客户端该怎么调用,是阻塞还是非阻塞,是同步还是异步,那么就需要对这个东西 ...

  6. Google Protobuf oneof使用

    一.编写proto协议 当我们某一个字段可能出现多种不同类型,那么就可以使用oneof.对于网络传输中的一个响应,可能出现不同的结构.例如,response可能是文章列表(包含标题,正文,作者,日期等 ...

  7. proto3 协议指引

    一.protocal buffer 是什么? 一种序列化机制. 什么是序列化? 一种转化为可存储和传输对象的过程. 序列化的方式有很多,那么proto有什么特殊的呢? 它的英文介绍里提到了neutra ...

  8. 【Protobuf速成指南】oneof类型的使用

    文章目录 2.3 oneof 类型 一.基本认识 二. 3.2 oneof相关函数 三.Contact2.3 改写 2.3 oneof 类型  本系列文章将通过对通讯录项目的不断完善,带大家由浅入深的 ...

  9. 【Protobuf协议】003-嵌套类型、更新一个消息类型、Any、Oneof、Map(映射)、包

    目录 七.嵌套类型 八.更新一个消息类型 九.Any 十.Oneof 1.概述 2.使用Oneof 3.Oneof 特色 4.向后兼容性问题 十一.Map(映射) 1.概述 2.向后兼容性问题 十二. ...

  10. Protobuf(二)proto3语法格式

    .proto文件有两种语法标准:proto2和proto3,我们以proto3为例,其语法格式如下: message <message_name> {<filed_rule> ...

最新文章

  1. java中基本字节输出流类是_java中基本输入输出流的解释
  2. addhandler php5-script php,htaccess和AddType/Addhandler
  3. 用matlab编程简单电子琴,基于MATLAB的数字信号发生器及简易电子琴设计论文.doc...
  4. php多进程 写入文件_PHP多进程中使用file_put_contents安全吗?
  5. 9.特殊权限 软连接 硬链接
  6. 直播、线上办公、IoT需求井喷,Wi-Fi 6如何防止网络“塞车”?
  7. 图像变换——图像反转
  8. 查看MySQL数据库大小
  9. Atitit.进程管理常用api
  10. TO-220与TO-220F的区别 封装
  11. 泛微E9 获取附件内容,泛微Ecology9获取附件范例,Ecology9附件、E9 附件下载及上传集成平台
  12. matlab newton插值法,matlab中newton插值法
  13. error:control reaches end of non-void function [-Werror=return-type]
  14. 响应“交通强国”战略,百度地图重构行业生态价值
  15. ubuntu 12.04中搭建nfs服务器
  16. OPPO加入连接标准联盟董事会;BOSE为领克09汽车打造Centerpoint环绕声音响系统 | 全球TMT...
  17. 南京java架构师工资_java架构师工资一般是多少?怎么提升才能获得高薪?
  18. Standard Deviation And Correlation
  19. 22.扩展.等保测评相关实务
  20. MUI学习笔记之图片上传和预览

热门文章

  1. k8s与日志--journalbeat源码解读
  2. Gzip, Bzip2,Xz压缩
  3. 账户余额“蒸发”暴露网银安全哪些漏洞?
  4. eclipse中MAVEN的web项目部署至TOMCAT的步骤
  5. [转]使用C#开发一个简单的P2P应用
  6. 10.企业安全建设入门(基于开源软件打造企业网络安全) --- 数据库安全
  7. 10.卷1(套接字联网API)---SCTP 客户/服务器程序例子
  8. 42.验证和授权(2)
  9. 23. Yii 组件事件
  10. 22. DOM 简介