【问题标题】:XXX_* type in generated *.pb.go fileXXX_* 输入生成的 *.pb.go 文件
【发布时间】:2018-11-15 04:33:55
【问题描述】:

我正在编写一个关于 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:"-"`
}

【问题讨论】:

标签: go protocol-buffers grpc


【解决方案1】:

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

此外,XXX 字段允许您公开extensions,它们是 Proto2 的一部分。它们在 Proto3 中被删除以支持 Any,但库仍然需要支持它们。

至于你应该如何处理这些?我只想让他们独自一人,不要引用他们。您不需要设置它们,也不需要阅读它们。 Go protobuf 库将为您处理它们。

【讨论】:

  • 在某些情况下,这些字段会阻止我们将生成的类型用于运行时 BigQuery 架构推断和插入,因为它们没有对应的表列。所以我们不能只是离开他们,假装他们不在那里。
  • 听起来应该更新架构推断以忽略这些字段。也许提交一个错误?
  • 一年以来已经有一个bug,但它仍然存在:github.com/googleapis/google-cloud-go/issues/1119
【解决方案2】:

如果您想在生成时专门排除它们,可以将其添加到您的文件中

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;

编辑:样式

【讨论】:

    【解决方案3】:

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

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

    更快的速度和更多的生成代码

    没有指针的字段会减少垃圾收集器的时间。更多的 代码生成带来更方便的方法。

    还包括其他二进制文件:

    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)
    

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

    去 github.com/gogo/protobuf/proto
    去获取 github.com/gogo/protobuf/{binary}
    去获取 github.com/gogo/protobuf/gogoproto

    安装lib后使用

    protoc --gogofaster_out=plugins=grpc
    

    【讨论】:

      猜你喜欢
      • 2022-10-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-05-14
      • 1970-01-01
      • 2022-10-13
      相关资源
      最近更新 更多