Protocol Buffers 包含一组预定义的“通用类型”(Well-Known Types, WKTs),用于处理常见的编程需求,并为常用概念提供标准定义。这些类型内置于 Protocol Buffers 中,并可在所有支持的编程语言中使用。
通用类型具有多个重要目的:
本页面介绍了 Protocol Buffers 库中定义的内置通用类型消息。有关用于描述 Protocol Buffer 消息本身的描述符系统的信息,请参阅描述符和编译管道。
来源:src/google/protobuf/struct.pb.h1-100 src/google/protobuf/any.pb.h1-60 src/google/protobuf/wrappers.pb.h1-100 src/google/protobuf/struct.pb.h src/google/protobuf/type.pb.h src/google/protobuf/wrappers.pb.h src/google/protobuf/timestamp.pb.h src/google/protobuf/duration.pb.h src/google/protobuf/field_mask.pb.h src/google/protobuf/api.pb.h src/google/protobuf/empty.pb.h
Protocol Buffers 的通用类型可以分为几个逻辑类别:
来源:src/google/protobuf/struct.pb.h src/google/protobuf/type.pb.h src/google/protobuf/wrappers.pb.h src/google/protobuf/timestamp.pb.h src/google/protobuf/duration.pb.h src/google/protobuf/empty.pb.h src/google/protobuf/timestamp.pb.h src/google/protobuf/duration.pb.h src/google/protobuf/field_mask.pb.h src/google/protobuf/api.pb.h src/google/protobuf/empty.pb.h src/google/protobuf/timestamp.pb.h src/google/protobuf/duration.pb.h src/google/protobuf/field_mask.pb.h src/google/protobuf/api.pb.h src/google/protobuf/empty.pb.h
这些类型提供与 JSON 数据结构的无缝互操作性,允许在 Protocol Buffers 和 JSON 之间进行转换。
Struct 类型表示一个结构化数据值,包含映射到动态类型值的字段。这本质上等同于一个 JSON 对象。
Struct 类型可以通过其 `fields` 映射包含嵌套结构,该映射将字符串键映射到 `Value` 对象。`Value` 类型本身是一个 `oneof` 类型,可以表示任何 JSON 兼容的值:
使用示例
来源:src/google/protobuf/struct.pb.h63-100 src/google/protobuf/struct.pb.h326-523 src/google/protobuf/struct.pb.h563-859 src/google/protobuf/struct.pb.h129-323
包装器类型封装了原始 Protocol Buffer 类型,提供了一种区分原始类型的默认值与其缺失(null)值的方法。
| 包装器类型 | 包装的原始类型 | 描述 |
|---|---|---|
DoubleValue | double | Double 值的包装器 |
FloatValue | 浮点数 | Float 值的包装器 |
Int64Value | int64 | Int64 值的包装器 |
UInt64Value | uint64 | UInt64 值的包装器 |
Int32Value | int32 | Int32 值的包装器 |
UInt32Value | uint32 | UInt32 值的包装器 |
BoolValue | bool | Boolean 值的包装器 |
StringValue | 字符串 | String 值的包装器 |
BytesValue | bytes | Bytes 值的包装器 |
每个包装器消息都包含一个名为 `value` 的字段,其类型与相应的原始类型相同。这些包装器的主要目的是允许在某些地方(例如在 maps 或作为 optional 字段)使用 null 值。
来源:src/google/protobuf/wrappers.pb.h104-168 src/google/protobuf/wrappers.pb.cc30-178
Protocol Buffers 提供了两种通用类型来表示时间概念:
Timestamp 类型表示一个独立于任何时区或日历的时间点,表示为自 1970 年 1 月 1 日 UTC 以来的秒数和纳秒数。
message Timestamp {
int64 seconds = 1;
int32 nanos = 2;
}
Duration 类型表示一个有符号的、固定长度的时间跨度,表示为秒数和纳秒数。
message Duration {
int64 seconds = 1;
int32 nanos = 2;
}
这两种类型具有相似的结构,其中 `seconds` 表示完整的秒部分,`nanos` 表示纳秒精度的小数秒部分。
来源:src/google/protobuf/timestamp.pb.h src/google/protobuf/timestamp.pb.cc30-54 src/google/protobuf/duration.pb.h src/google/protobuf/duration.pb.cc30-54
Protocol Buffers 包含多种处理常见编程场景的实用类型。
Any 类型允许您打包和解包任意 Protocol Buffer 消息,从而能够在没有编译时定义的情况下传输消息。
Any 类型包含:
type_url:一个唯一标识序列化消息类型的 URLvalue:嵌入消息的序列化二进制数据关键方法
PackFrom():序列化消息并将其存储在 Any 对象中UnpackTo():将嵌入消息反序列化到提供的消息对象中Is<T>():检查嵌入消息是否为 T 类型来源: src/google/protobuf/any.pb.h72-240 src/google/protobuf/any.pb.cc34-62
Empty 类型是一个简单的消息,没有字段。当操作不需要参数或不返回数据,但 API 又需要消息类型时,它非常有用。
来源: src/google/protobuf/empty.pb.h src/google/protobuf/empty.pb.cc30-46
FieldMask 类型用于指定消息中用于更新、读取或写入操作的字段子集。当只需要更新资源的某些部分时,这在 API 实现中尤其有用。
message FieldMask {
repeated string paths = 1;
}
字段掩码包含相对于特定消息类型的字段路径列表。每条路径都是一个点分隔的字段名序列,表示消息中的字段或嵌套字段。
来源: src/google/protobuf/field_mask.pb.h72-217 src/google/protobuf/field_mask.pb.cc30-53
Protocol Buffers 包含一组代表 Protocol Buffer 类型系统自身的知名类型,这些类型对于反射和运行时类型信息非常有用。
这些类型提供了以编程方式表示和操作 Protocol Buffer 定义的方法。
Type:表示 Protocol Buffer 消息类型Field:表示消息类型中的字段Enum:表示枚举类型EnumValue:表示枚举中的值Option:表示应用于类型、字段或值的选项SourceContext:表示源文件上下文Syntax:表示 Protocol Buffer 语法版本来源: src/google/protobuf/type.pb.h72-650 src/google/protobuf/type.pb.cc30-195 src/google/protobuf/source_context.pb.h72-137
API 知名类型提供了一种使用 Protocol Buffers 定义 API 的方法。
这些类型用于以与语言无关的方式描述 API。
Api:表示一个 API,作为方法的集合Method:表示 API 中的方法,包括请求和响应类型Mixin:表示 API 导入的 mixin来源: src/google/protobuf/api.pb.h82-290 src/google/protobuf/api.pb.h295-427 src/google/protobuf/api.pb.cc30-130
知名类型在所有支持的 Protocol Buffer 语言中都提供惯用的实现。在 C++ 中,知名类型在 google::protobuf 命名空间中作为生成的类提供。
这些类型在 Protocol Buffer 运行时中内置了特殊的序列化和验证逻辑,可确保所有语言实现的行为一致。例如:
在您自己的 Protocol Buffer 定义中使用知名类型时,您可以使用以下方式导入它:
来源: src/google/protobuf/struct.pb.h src/google/protobuf/any.pb.h src/google/protobuf/timestamp.pb.h
在使用知名类型时,请考虑以下最佳实践:
使用适当的包装器类型,以区分零值/空值和未设置字段。
使用 Any 类型,当您需要序列化未知类型的消息时,尤其是在插件系统或 RPC 框架中。
使用 Timestamp 和 Duration 而非自定义时间表示,以确保互操作性。
在 API 中使用 FieldMask 进行部分更新,允许客户端指定要更新的字段。
当您需要在 Protocol Buffers 中直接表示 JSON 风格的数据结构时,使用 Struct、Value 和 ListValue。
谨慎使用 Empty - 虽然它可以用作占位符,但请考虑更具体的类型是否能更好地表达您的意图。
考虑语言特定的实用方法,这些方法为知名类型提供,因为它们通常提供超出基本 Protocol Buffer 操作的功能。
来源: src/google/protobuf/any.pb.h128-183 src/google/protobuf/struct.pb.h129-861 src/google/protobuf/field_mask.pb.h217-300