菜单

知名类型

相关源文件

Protocol Buffers 包含一组预定义的“通用类型”(Well-Known Types, WKTs),用于处理常见的编程需求,并为常用概念提供标准定义。这些类型内置于 Protocol Buffers 中,并可在所有支持的编程语言中使用。

目的与范围

通用类型具有多个重要目的:

  • 它们为常见的编程概念提供了统一的接口。
  • 它们有助于在语言实现之间标准化序列化。
  • 它们使得使用 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 兼容类型

这些类型提供与 JSON 数据结构的无缝互操作性,允许在 Protocol Buffers 和 JSON 之间进行转换。

Struct 类型

Struct 类型表示一个结构化数据值,包含映射到动态类型值的字段。这本质上等同于一个 JSON 对象。

Struct 类型可以通过其 `fields` 映射包含嵌套结构,该映射将字符串键映射到 `Value` 对象。`Value` 类型本身是一个 `oneof` 类型,可以表示任何 JSON 兼容的值:

  • 原始值:null、boolean、number 或 string
  • 复杂值:嵌套的 struct 或 list

使用示例

  • 表示配置数据
  • 存储半结构化数据
  • 处理 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)值的方法。

包装器类型包装的原始类型描述
DoubleValuedoubleDouble 值的包装器
FloatValue浮点数Float 值的包装器
Int64Valueint64Int64 值的包装器
UInt64Valueuint64UInt64 值的包装器
Int32Valueint32Int32 值的包装器
UInt32Valueuint32UInt32 值的包装器
BoolValueboolBoolean 值的包装器
StringValue字符串String 值的包装器
BytesValuebytesBytes 值的包装器

每个包装器消息都包含一个名为 `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:一个唯一标识序列化消息类型的 URL
  • value:嵌入消息的序列化二进制数据

关键方法

  • 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

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 类型

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 运行时中内置了特殊的序列化和验证逻辑,可确保所有语言实现的行为一致。例如:

  • Timestamp 和 Duration 强制执行秒和纳秒的有效范围。
  • Any 类型提供用于打包和解包消息的辅助方法。
  • Struct 和 Value 类型提供与 JSON 的无缝转换。

在您自己的 Protocol Buffer 定义中使用知名类型时,您可以使用以下方式导入它:

来源: src/google/protobuf/struct.pb.h src/google/protobuf/any.pb.h src/google/protobuf/timestamp.pb.h

最佳实践

在使用知名类型时,请考虑以下最佳实践:

  1. 使用适当的包装器类型,以区分零值/空值和未设置字段。

  2. 使用 Any 类型,当您需要序列化未知类型的消息时,尤其是在插件系统或 RPC 框架中。

  3. 使用 Timestamp 和 Duration 而非自定义时间表示,以确保互操作性。

  4. 在 API 中使用 FieldMask 进行部分更新,允许客户端指定要更新的字段。

  5. 当您需要在 Protocol Buffers 中直接表示 JSON 风格的数据结构时,使用 Struct、Value 和 ListValue。

  6. 谨慎使用 Empty - 虽然它可以用作占位符,但请考虑更具体的类型是否能更好地表达您的意图。

  7. 考虑语言特定的实用方法,这些方法为知名类型提供,因为它们通常提供超出基本 Protocol Buffer 操作的功能。

来源: src/google/protobuf/any.pb.h128-183 src/google/protobuf/struct.pb.h129-861 src/google/protobuf/field_mask.pb.h217-300