安装protoc
从 Protobuf Releases 下载最新版本的压缩包:
|
|
然后解压到 /use/local 目录下:
|
|
如果提示 Command 'unzip' not found. 的错误,按照提示先安装:
|
|
然后再执行解压操作。
解压完成后执行 protoc --version 查看版本,如果能正常显示版本就说明安装成功。
|
|
安装protoc-gen-go
proton-gen-go 是编译器 protoc 的一个插件,它能够通过 .proto 文件生成 Go 语言代码。
|
|
一个简单的例子
如果使用 VSCode 编辑器的话推荐一个 protobuf 插件:vscode-proto3 ,提供了语法高亮、代码补全、格式化等功能。
创建一个 studu-go 文件夹,然后在文件夹内创建一个 user 文件夹,在 user 文件夹内新建 user.proto :
|
|
第 1 行声明使用 proto3 版本,不写的话默认是 proto2 版本。
第 3 行声明 proto 文件所在的包名,相当于 proto 文件的命名空间,防止不同的消息类型产生命名冲突,该字段是可选的。
第 4 行声明了要生成的 .pb.go 文件保存的路径(这个放在后面生成代码时讲)和 .pb.go 文件的包名,用分号 ; 隔开。
第 6 行为想要编码的数据结构定义了一个 message 类型,其中每个字段后面的 =1, =2 表示字段在二进制编码时使用的唯一标记,关键字 repeated 表示该数据可重复,类比 Go 语言中的 slice 。
完整的语法可以查询官方文档:Protocol Buffers Documentation 。
接着在 /user 目录下生成 Go 代码:
|
|
这会在 /user 目录下生成 user.pb.go 文件。
protoc 命令有两个重要参数:protoc --go_out=$DST_DIR $SRC_DIR/<name>.proto :
第二个参数指定 .proto 文件的路径,这个很好理解。
第一个参数 go_out 表示 Go 代码输出的目录,如果在 .proto 文件中定义了 go_package=$PATH, 那么最终 Go 代码输出的目录是 $DST_DIR/$PATH ,下面举几个例子说明:
当前的文件结构是这样的:
/study-go/
├── go.mod
├── go.sum
├── main.go
└── user
└── user.proto
-
如果在
/study-go目录下执行:1 2 3# go_package=".;user" # ~/study-go protoc --go_out=. ./user/user.proto这样定义的输出路径是
.也即当前目录,最终会在/study-go目录下生成user.pb.go。 -
如果在
/study-go目录下执行:1 2 3# go_package="/user;user" # ~/study-go protoc --go_out=. ./user/user.proto这样定义的输出路径是
./user,也即/study-go/user。 -
如果在
/study-go/user目录下执行:1 2 3# go_package=".;user" # ~/study-go/user protoc --go_out=. ./user.proto这样定义的输出路径也是
.也即当前目录,最终会在/study-go/user目录下生成user.pb.go。
总的来说,最后输出的路径和当前执行命令的目录、go_out 参数、go_package 都有关系,官方推荐尽量写在 go_package 中,这样可以缩短 protoc 命令的长度。
弄清楚生成路径之后,就可以编写 main.go 来实现一个简单的程序了:
|
|
在主函数中定义个一个 User 类型的变量,然后使用 data 变量保存 proto.Marshal 序列化产生的数据,最后用 proto.Unmarshal 反序列化,最后的 userTest 会和 u 有相同的数据。