← 返回
后端开发 2026.03.06

Go工程师体系课 protobuf_guide

后端开发

1. 简介

Protocol Buffers(简称 protobuf)是 Google 开发的一种语言无关、平台无关、可扩展的结构化数据序列化机制。与 JSON、XML 等序列化方式相比,protobuf 更小、更快、更简单。

2. 安装

2.1 安装 protoc 编译器

protoc 编译器用于将 .proto 文件编译成特定编程语言的源代码。

  1. https://github.com/protocolbuffers/protobuf/releases 下载适合您平台的预编译版本。
  2. 解压后,将 bin 目录下的 protoc 可执行文件拷贝到系统的 PATH 环境变量包含的目录下(例如 /usr/local/bin)。
  3. 验证安装:

bash protoc --version

2.2 安装 protobuf 运行时环境

不同编程语言需要安装相应的 protobuf 运行时环境。例如,对于 Go 语言:

go install google.golang.org/protobuf/cmd/protoc-gen-go@latest

确保将 $GOPATH/bin 添加到系统的 PATH 环境变量中,以便 protoc 可以找到 protoc-gen-go 插件。

3. 定义消息类型

创建一个 .proto 文件,定义数据结构。例如,创建 student.proto

syntax = "proto3";

package main;

message Student {
  string name = 1;
  bool male = 2;
  repeated int32 scores = 3;
}

在当前目录下执行以下命令,生成 Go 语言的代码:

protoc --go_out=. student.proto

这将生成 student.pb.go 文件,包含了 Student 类型的 Go 语言实现。

4. 使用生成的代码

在 Go 语言中,可以使用生成的代码进行数据的序列化和反序列化。

package main

import (
  "fmt"
  "log"

  "google.golang.org/protobuf/proto"
)

func main() {
  student := &Student{
    Name:   "Alice",
    Male:   false,
    Scores: []int32{90, 95, 100},
  }

  // 序列化
  data, err := proto.Marshal(student)
  if err != nil {
    log.Fatal("Marshaling error: ", err)
  }

  // 反序列化
  newStudent := &Student{}
  err = proto.Unmarshal(data, newStudent)
  if err != nil {
    log.Fatal("Unmarshaling error: ", err)
  }

  fmt.Println("Student:", newStudent)
}

5. 字段规则

  • optional:表示该字段是可选的,可以设值也可以不设值。如果没有设值,将使用默认值进行初始化。
  • repeated:表示该字段可以重复任意次数使用,类似于动态数组。

注意:在 proto3 中,required 关键字已被移除,所有字段默认都是可选的。

6. 枚举和嵌套类型

可以在 .proto 文件中定义枚举类型和嵌套的消息类型。例如:

syntax = "proto3";

package main;

message Person {
  string name = 1;
  int32 id = 2;
  string email = 3;

  enum PhoneType {
    MOBILE = 0;
    HOME = 1;
    WORK = 2;
  }

  message PhoneNumber {
    string number = 1;
    PhoneType type = 2;
  }

  repeated PhoneNumber phones = 4;
}

7. 向后兼容性

在更新 .proto 文件时,为了保持向后兼容性,应遵循以下规则:

  • 不要更改已有字段的编号。
  • 不要删除已有的字段。
  • 可以添加新的字段,但必须使用新的编号。
  • 可以添加新的枚举值。

遵循这些规则可以确保旧的代码仍然可以解析新的消息格式。

8. 更多资源