一、protobuf 安装
1、protobuf安装
下载网址:https://github.com/protocolbuffers/protobuf/releases
安装并添加环境变量
命令行查看安装是否成功:
protoc --version
2、go语言protobuf包
go install google.golang.org/protobuf/cmd/protoc-gen-go@latest
# 查看是否安装成功
protoc-gen-go --version
- 特别注意:
go get -u github.com/golang/protobuf/protoc-gen-go
为旧版本!!!
3、安装vscode插件:vscode-proto3
二、 protobuf 结构
- 文件名.proto
syntax = "proto3";
package protoData;
option go_package="/protoData"; // 使用go语言必须添加
message SearchRequest {
string query = 1;
int32 page_number = 2;
int32 result_per_page = 3;
}
1、编号
- 最小字段编号是 1,最大的是 536,870,911。不能使用数字 19000 到 19999 (保留的编号)
2、字段规则
- 单数:0-1个值。这是 proto3 语法的默认字段规则。
repeated
:0-多个值。重复值的顺序将被保留。repeated
:其他消息import "myproject/other_protos.proto";
导入其他文件中消息
3、注释
//
/* ... */
4、数据类型
proto类型 | go类型 | 备注 | proto类型 | go类型 | 备注 |
---|---|---|---|---|---|
double | float64 | float | float32 | ||
int32 | int32 | int64 | int64 | ||
uint32 | uint32 | uint64 | uint64 | ||
sint32 | int32 | 适合负数 | sint64 | int64 | 适合负数 |
fixed32 | uint32 | 固长编码,适合大于2^28的值 | fixed64 | uint64 | 固长编码,适合大于2^56的值 |
sfixed32 | int32 | 固长编码 | sfixed64 | int64 | 固长编码 |
bool | bool | string | string | UTF8 编码,长度不超过 2^32 | |
bytes | []byte | 任意字节序列,长度不超过 2^32 |
(1)任意类型(Any)
Any 可以表示不在 .proto 中定义任意的内置类型。
import "google/protobuf/any.proto";
message ErrorStatus {
string message = 1;
repeated google.protobuf.Any details = 2;
}
(2)oneof
message SampleMessage {
oneof test_oneof {
string name = 4;
SubMessage sub_message = 9;
}
}
(3)map
message MapRequest {
map<string, int32> points = 1;
}
5、默认值
- 字符串,空字符串。
- 字节,空字节。
- 布尔值, false。
- 数字类型,零。
- enums,第一个定义的 enum value,它必须是 0。
- 消息字段,未设置该字段。它的确切值取决于语言。
三、生成相应代码
1、生成go命令
syntax = "proto3";
package protoData; // go语言可以没有
option go_package="/protoData"; // go语言必须有
message User {
string name = 1;
int32 age = 2;
}
# 必须有:option go_package="/protoData";
# 生成文件在包名目录下
protoc --go_out=. *.proto
四、go-protobuf
go mod init 项目名 # 创建项目
go get google.golang.org/protobuf/proto # 添加依赖
go mod tidy # 更新依赖
- 特别注意:
github.com/golang/protobuf/proto
为旧版本!!!
package main
import (
"fmt"
"go-protobuf/protoD" // 项目名/proto数据包名
"google.golang.org/protobuf/proto"
)
func main() {
user1 := &protoD.User{Name: "小明", Age: 16}
fmt.Println(user1)
// 序列化
data, err := proto.Marshal(user1)
if err != nil {
fmt.Println("序列化错误!")
}
fmt.Println(data)
// 反序列化
user2 := protoD.User{}
err = proto.Unmarshal(data, &user2)
if err != nil {
fmt.Println("反序列化错误!")
}
fmt.Println(user2)
}
func (*Person) Reset()
: 将Person
消息重置为默认值。func (*Person) String() string
: 返回一个字符串,包含Person
消息的文本表示形式。func (*Person) ProtoMessage()
: 使Person
结构体实现proto.Message
接口,这是在序列化和反序列化 Protobuf 消息时所需的。func (*Person) Descriptor() ([]byte, []int)
: 返回关于Person
消息类型的描述符信息。
特别注意,发生错误可能版本问题:
- go语言最新protobuf包:
go install google.golang.org/protobuf/cmd/protoc-gen-go@latest
✔- 旧版本:
go get -u github.com/golang/protobuf/protoc-gen-go
X
- 旧版本:
- protobuf定义中必须有:
option go_package="/自定义proto包名";
- go中引用proto文件:
项目名/自定义proto包名
- go中最新导包为:
"google.golang.org/protobuf/proto"
✔- 旧版本:
github.com/golang/protobuf/proto
X
- 旧版本: