8、Protocol Buffers (protobuf)
安装
下载:https://github.com/protocolbuffers/protobuf/releases/tag/v3.19.1
解压到任意位置
设置path:D:\protoc-3.19.1\bin
添加 go 代码生成:https://github.com/grpc-ecosystem/grpc-gateway
为 protoc 添加扩展
go install github.com/grpc-ecosystem/grpc-gateway/v2/protoc-gen-grpc-gateway@latest
go install github.com/grpc-ecosystem/grpc-gateway/v2/protoc-gen-openapiv2@latest
go install google.golang.org/protobuf/cmd/protoc-gen-go@latest
go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@latest
复制 GOPATH 里面的 D:\go\bin\bin\ 四个程序
到 GOROOT 里面 C:\Users\Administrator\go\bin
简单使用
书写 test.proto
syntax = "proto3"; // 指定使用哪个版本 package coolcar; // 当前包名 option go_package = "ginStart/proto/goproto;testPackage"; // 指定生成后的目录 ginStart/proto; // testPackage 指定生成后的包名 message Trip { string start = 1; // 类型 字段名 = 第几个字段 string end = 2; int64 duiation_sec = 3; int64 fee_cent = 4; }
书写 main.go
package main import "fmt" import testPackage "project/proto/goproto" // project 表示go.mod定义的包名 func main() { trip := testPackage.Trip{ Start: "aaa", } fmt.Println(&trip) }
创建 goproto 目录后
在 .proto 文件的文件夹下,调用命令
protoc --go_out=goproto --go_opt=paths=source_relative test.proto
JSON序列化 和 反序列化
.proto
message Person { string name = 1; int32 age = 2; }
.go
s := testPackage.Person{ Name: "ss", Age: 11, } // 序列化 b,err := proto.Marshal(&s) if err != nil { panic(err) } fmt.Printf("%X\n",b) // 0A027373100B //fmt.Println(b) // [10 2 115 115 16 11] // 反序列化 var temp testPackage.Person // 定义哪个结构进行解码 err = proto.Unmarshal(b,&temp) // 将解码后的内容放进 temp if err != nil { panic(err) } fmt.Println(&temp) // 将结构数据 转为 json字符串 b,err = json.Marshal(&temp) if err != nil { panic(err) } fmt.Printf("%s\n",b)
复合类型
proto
message Person { string name = 1; int32 age = 2; } message Trip { string start = 1; string end = 2; Person a = 3; Person b = 4; repeated Person c = 5; }
调用
trip := testPackage.Trip{ Start: "aaa", End: "bbb", A: &testPackage.Person{ Name: "名字", Age: 18, }, B: &testPackage.Person{ Name: "另外名字", Age: 20, }, C: []*testPackage.Person{ { Name: "11", Age: 11, }, { Name: "22", Age: 22, }, { Name: "22", Age: 22, }, }, } fmt.Println(&trip) //start:"aaa" end:"bbb" a:{name:"名字" age:18} b:{name:"另外名字" age:20} c:{name:"11" age:11} c:{name:"22" age:22} c:{name:"22" age:22}
枚举类型
.proto
enum NowStatus { ONESTATUS = 0; TWOSTATUS = 1; THREESTATUS = 2; FOURSTATUS = 3; } message Person { string name = 1; NowStatus status = 2; }
使用
// 直接使用 fmt.Println(testPackage.NowStatus_THREESTATUS) // THREESTATUS fmt.Println(testPackage.NowStatus(2)) // THREESTATUS // 混合使用 s := testPackage.Person{ Name: "cc", Status: testPackage.NowStatus_THREESTATUS, } fmt.Println(&s) //name:"cc" status:THREESTATUS