Google Protobuf 语言

Protocol Buffers 使用了一种中立、平台无关的语言来定义数据结构,使得不同编程语言、不同平台之间能够进行数据交互。Protocol Buffers 目前主要有 Proto2 和 Proto3 两个版本,Proto3 保持了与 Proto2 的一定程度的兼容性。但是,某些 Proto2 特性在 Proto3 中不再支持。

1. 标量类型

在 Protobuf 中,标量类型(Scalar Types)是指一些基本的数据类型,可以直接在 .proto 文件中定义并用于数据字段。这些类型对应于原生的简单数据类型,类似于编程语言中的整型、浮点型、布尔型等。

Document:https://protobuf.dev/programming-guides/proto3/#scalar

案例:在 protos 目录中创建 employee.proto 文件,定义 Employee 消息:

syntax = "proto3";


message Employee
{
  // 姓名
  string name = 1;
  // 年龄
  int32 age = 2;
  // 薪资
  double salary = 3;
  // 性别
  bool gender = 4;
}

注意:当创建数据字段时,每个字段都需要指定一个唯一的位置编号,用于区分不同的字段。

最后使用 protoc 编译器生成对应语言的操作代码:

protoc protos/employee.proto --python_out=output
protoc protos/employee.proto --cpp_out=output

2. 复杂类型

在 message 中也可以定义较为复杂的类型,例如:

  • 枚举类型:枚举类型用于定义一组命名常量
  • 嵌套消息:在一个消息中嵌套另一个消息
  • 重复字段:表示一个字段可以出现零次或多次,可以理解为动态数组
  • 映射字段:表示键值对的集合

案例:在 protos 目录中创建 developer.proto 文件,定义 Developer 消息:

syntax = "proto3";


message Other
{
    int32 v1 = 1;
    int32 v2 = 2;
}

enum Week
{
  // 第一个枚举项的值必须为 0,在 proto2 中没有此限制,这是因为对于枚举类型默认值是 0
  // 后续的枚举项值可以是任意的、不重复的
  Mon = 0;
  Tue = 3;
  Wed = 4;
  Thu = 5;
  Fri = 6;
  Sat = 7;
  Sun = 8;
}


message Developer
{
  string name = 1;
  Week week = 2;
  repeated int32 list = 3;
  map<string, int32> map = 4;
  Other oher = 5;
}

执行如下命令生成对应语言的操作代码:

protoc protos/developer.proto --cpp_out=output

注意:message 允许嵌套定义,即:message 中嵌套另外一个 message。在 protos 目录中创建 nested.proto 文件,定义 Developer 消息:

syntax = "proto3";


message Nested
{
    string name = 1;
    map<string, int32> teles = 2;

    message Other
    {
        int32 v1 = 1;
        int32 v2 = 2;
    }
    Other other = 3;
}
protoc protos/nested.proto --cpp_out=output

3. import 用法

import 指令允许在 Protobuf 中将一个 .proto 文件中的定义引入到另一个 .proto 文件中,以便在后者中使用前者中定义的消息类型、枚举类型等。

这种组织方式有助于管理大型的 .proto 定义,使得可以将不同的消息类型分别定义在不同的文件中,并通过 import 将它们组合在一起。import 指令通常位于文件顶部,其语法类似于其他编程语言中的导入或引用语句。

案例:在 protos 目录中创建 specialist.proto 文件,定义 Specialist 消息:

syntax = "proto3";

// 导入 employee.proto 文件
import "protos/employee.proto";

message Specialist
{
  string name = 1;
  int32 age = 2;
  // 使用其他 employee.proto 定义的数据类型
  Employee emp = 3;
}

执行如下命令生成对应语言的操作代码:

protoc protos/specialist.proto --cpp_out=output

4. package 用法

在 Protobuf 中,package 关键字用于定义一个命名空间,用于组织和管理定义的消息类型。它有助于避免命名冲突,并使得代码更加清晰和易于维护。

在 protos 目录中创建 common1.proto 文件,在 foo.bar1 中定义 Information 消息:

syntax = "proto3";

package foo.bar1;

message Information
{
  string info_content1 = 1;
  string info_content2 = 2;
}

在 protos 目录中创建 common2.proto 文件,在 foo.bar2 中定义 Information 消息:

syntax = "proto3";

package foo.bar2;

message Information
{
  int32 info_id1 = 1;
  int32 info_id2 = 2;
}

在 protos 目录中创建 common.proto 文件,定义 Message 消息:

syntax = "proto3";

import "protos/common1.proto";
import "protos/common2.proto";


message Message
{
  // 通过包名访问 Message 类型
  foo.bar1.Information info1 = 1;
  foo.bar2.Information info2 = 2;
}
protoc protos/common.proto --cpp_out=output
未经允许不得转载:一亩三分地 » Google Protobuf 语言
评论 (0)

5 + 1 =