XXX_* 键入生成的 *.pb.go 文件

XXX_* type in generated *.pb.go file

我正在研究有关 gRPC 的 tutorial。当我生成 .pb.go 文件时,我在我的结构中得到了一些 XXX_* 类型。

这是我的 consignment.proto 文件:

syntax = "proto3";

package go.micro.srv.consignment; 

service ShippingService {
    rpc CreateConsignment(Consignment) returns (Response) {}
}

message Consignment {
    string id = 1;
    string description = 2;
    int32 weight = 3;
    repeated Container containers = 4;
    string vessel_id = 5;
}

message Container {
    string id = 1;
    string customer_id = 2;
    string origin = 3;
    string user_id = 4;
}

message Response {
    bool created = 1;
    Consignment consignment = 2;
}

这是 .pb.go 文件中的结构。谁能告诉我为什么我的 struct 中有 3 个 XXX 类型?结构不应该反映我在 proto 中定义的内容吗?

type Consignment struct {
    Id                   string       `protobuf:"bytes,1,opt,name=id" json:"id,omitempty"`
    Description          string       `protobuf:"bytes,2,opt,name=description" json:"description,omitempty"`
    Weight               int32        `protobuf:"varint,3,opt,name=weight" json:"weight,omitempty"`
    Containers           []*Container `protobuf:"bytes,4,rep,name=containers" json:"containers,omitempty"`
    VesselId             string       `protobuf:"bytes,5,opt,name=vessel_id,json=vesselId" json:"vessel_id,omitempty"`
    XXX_NoUnkeyedLiteral struct{}     `json:"-"`
    XXX_unrecognized     []byte       `json:"-"`
    XXX_sizecache        int32        `json:"-"`
}

Protobuf 库使用 XXX_ 类型来存储未知字段。当您解码原型时,序列化数据中可能有库不知道如何处理的其他字段。例如,当 reader 和数据的编写者使用原始文件的不同副本时,就会发生这种情况。此功能有助于在不同时间构建的客户端和服务之间实现向后兼容性。

此外,XXX 字段允许您公开 extensions, which were part of Proto2. They were removed in Proto3 in favor of Any,但图书馆仍然需要支持它们。

至于你应该用这些做什么?我会让他们一个人呆着,不要引用他们。您不需要设置它们,也不需要读取它们。 Go protobuf 库将为您处理它们。

如果你想在生成时特别排除它们,你可以将它添加到你的文件中

import "github.com/gogo/protobuf/gogoproto/gogo.proto";
option (gogoproto.goproto_unkeyed_all) = false;
option (gogoproto.goproto_unrecognized_all) = false;
option (gogoproto.goproto_sizecache_all) = false;

编辑:样式

golang 的官方 protobuffer 生成器仍然包含 XXX_ 字段,问题仍然悬而未决,决定是否删除它,但您可以使用 gogo 第三方生成器。我用了很长时间没有问题。只需使用 gogofaster_out

https://github.com/gogo/protobuf
以下是讨论排除 XXX_ 字段的部分

More Speed and more generated code

Fields without pointers cause less time in the garbage collector. More code generation results in more convenient methods.

Other binaries are also included:

protoc-gen-gogofast (same as gofast, but imports gogoprotobuf)
protoc-gen-gogofaster (same as gogofast, without XXX_unrecognized, less pointer fields)
protoc-gen-gogoslick (same as gogofaster, but with generated string, gostring and equal methods)

安装任何这些二进制文件都很容易。只需 运行:

go get github.com/gogo/protobuf/proto
go get github.com/gogo/protobuf/{binary}
go get github.com/gogo/protobuf/gogoproto

安装库后使用

protoc --gogofaster_out=plugins=grpc