Language Guide (proto3) | proto3 语言指南(八)未知字段和任意类型
未知字段和任意类型篇幅较少,因此将他们合并到本文进行描述。
Unknown Fields - 未知字段
未知字段是格式良好的协议缓冲区序列化数据,表示解析器无法识别的字段。例如,当一个旧二进制代码解析一个带有新字段的新二进制代码发送的数据时,这些新字段在旧二进制代码中成为未知字段。
最初,proto3
消息在解析过程中总是丢弃未知字段,但在3.5版中,我们重新引入了未知字段的保留,以匹配proto2
的行为。在版本3.5和更高版本中,解析期间保留未知字段,并将其包含在序列化输出中。
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_
。
不同的语言实现将支持运行时库助手以类型安全的方式打包和解包任何值——例如,在Java
中,Any
类型有特殊的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 ...
}
}
目前,用于处理Any
类型的运行库正在开发中。
如果您已经熟悉proto2
语法,那么Any
类型可以保存任意proto3
消息,类似于可扩展的proto2
消息。