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

相关