Proto3 Any与Oneof(转载)
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(转载)相关推荐
- 初识Protobuf协议
本文作为Protobuf入门学习的第一篇文章,将简单介绍Protobuf协议以及如何使用Protobuf来实现序列化与反序列化. 原文地址:https://mp.weixin.qq.com/s/QbL ...
- Protobuf学习入门(一)
笔者最近在学习使用tensorflow/serving,其中有不少涉及Protobuf相关的内容,因此接触学习了Prorobuf,记录于此,希望能对读者有所启发. 本文作为Protobuf入门 ...
- Proto3使用指南
这篇指南讲述如何使用Protocol Buffers来结构化你的Protocol Buffer数据,包括.proto文件语法以及如何从.proto文件生成你的访问类型.本文主要涵盖了proto3的语法 ...
- Protobuf 的 proto3 与 proto2 的区别
Protobuf 的 proto3 与 proto2 的区别 转载自:https://solicomo.com/network-dev/protobuf-proto3-vs-proto2.html 这 ...
- gRPC学习记录(三)--proto3知识
在上一篇中,得知proto文件是定义服务端和客户端通讯接口的标准,说白了就是客户端该传什么样的参数,服务端该返回什么样子的参数,客户端该怎么调用,是阻塞还是非阻塞,是同步还是异步,那么就需要对这个东西 ...
- Google Protobuf oneof使用
一.编写proto协议 当我们某一个字段可能出现多种不同类型,那么就可以使用oneof.对于网络传输中的一个响应,可能出现不同的结构.例如,response可能是文章列表(包含标题,正文,作者,日期等 ...
- proto3 协议指引
一.protocal buffer 是什么? 一种序列化机制. 什么是序列化? 一种转化为可存储和传输对象的过程. 序列化的方式有很多,那么proto有什么特殊的呢? 它的英文介绍里提到了neutra ...
- 【Protobuf速成指南】oneof类型的使用
文章目录 2.3 oneof 类型 一.基本认识 二. 3.2 oneof相关函数 三.Contact2.3 改写 2.3 oneof 类型 本系列文章将通过对通讯录项目的不断完善,带大家由浅入深的 ...
- 【Protobuf协议】003-嵌套类型、更新一个消息类型、Any、Oneof、Map(映射)、包
目录 七.嵌套类型 八.更新一个消息类型 九.Any 十.Oneof 1.概述 2.使用Oneof 3.Oneof 特色 4.向后兼容性问题 十一.Map(映射) 1.概述 2.向后兼容性问题 十二. ...
- Protobuf(二)proto3语法格式
.proto文件有两种语法标准:proto2和proto3,我们以proto3为例,其语法格式如下: message <message_name> {<filed_rule> ...
最新文章
- java中基本字节输出流类是_java中基本输入输出流的解释
- addhandler php5-script php,htaccess和AddType/Addhandler
- 用matlab编程简单电子琴,基于MATLAB的数字信号发生器及简易电子琴设计论文.doc...
- php多进程 写入文件_PHP多进程中使用file_put_contents安全吗?
- 9.特殊权限 软连接 硬链接
- 直播、线上办公、IoT需求井喷,Wi-Fi 6如何防止网络“塞车”?
- 图像变换——图像反转
- 查看MySQL数据库大小
- Atitit.进程管理常用api
- TO-220与TO-220F的区别 封装
- 泛微E9 获取附件内容,泛微Ecology9获取附件范例,Ecology9附件、E9 附件下载及上传集成平台
- matlab newton插值法,matlab中newton插值法
- error:control reaches end of non-void function [-Werror=return-type]
- 响应“交通强国”战略,百度地图重构行业生态价值
- ubuntu 12.04中搭建nfs服务器
- OPPO加入连接标准联盟董事会;BOSE为领克09汽车打造Centerpoint环绕声音响系统 | 全球TMT...
- 南京java架构师工资_java架构师工资一般是多少?怎么提升才能获得高薪?
- Standard Deviation And Correlation
- 22.扩展.等保测评相关实务
- MUI学习笔记之图片上传和预览
热门文章
- k8s与日志--journalbeat源码解读
- Gzip, Bzip2,Xz压缩
- 账户余额“蒸发”暴露网银安全哪些漏洞?
- eclipse中MAVEN的web项目部署至TOMCAT的步骤
- [转]使用C#开发一个简单的P2P应用
- 10.企业安全建设入门(基于开源软件打造企业网络安全) --- 数据库安全
- 10.卷1(套接字联网API)---SCTP 客户/服务器程序例子
- 42.验证和授权(2)
- 23. Yii 组件事件
- 22. DOM 简介