【问题标题】:protoc generates value instead of pointer (Go)protoc 生成值而不是指针(Go)
【发布时间】:2020-06-18 16:07:30
【问题描述】:

问题:

我在根目录中有 2 个文件。 我使用 Makefile 从 .proto 文件生成 Go 代码。

但 Video 结构中的语言字段是一个值,而不是指向该值的指针。 Video 结构中的 subtitles 字段是一个值数组,而不是指向该值的指针数组。

问题是:

如何让 protoc 生成指向该值的指针?

video.pb.go

type Video struct {
    state protoimpl.MessageState
    sizeCache protoimpl.SizeCache
    unknownFields protoimpl.UnknownFields

    Id        string              `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"`
    Title     string              `protobuf:"bytes,2,opt,name=title,proto3" json:"title,omitempty"`

    // I need *language.ISO639_1 below
    Languages language.ISO639_1   `protobuf:"varint,3,opt,name=languages,proto3,enum=language.ISO639_1" json:"languages,omitempty"`

    // I need []*language.ISO639_1 below
    Subtitles []language.ISO639_1 `protobuf:"varint,4,rep,packed,name=subtitles,proto3,enum=language.ISO639_1" json:"subtitles,omitempty"`
}

生成文件

gen:
   # Video
   protoc -I. --go_out=plugins=grpc,paths=source_relative:video video.proto

   # Language
   protoc -I. --go_out=plugins=grpc,paths=source_relative:language language.proto

语言.proto

syntax = "proto3";

package language;

option go_package = "example.com/group/repo/language;language";

enum ISO639_1 {
    UNKNOWN = 0;
    zh      = 1;
}

video.proto

syntax = "proto3";

package video;

import "language.proto";

option go_package = "example.com/group/repo/video;video";

message Video {
             string            id        = 1;
             string            title     = 2;
             language.ISO639_1 language  = 3;
    repeated language.ISO639_1 subtitles = 4;
}

协议版本:libprotoc 3.11.4

【问题讨论】:

  • 可能是this的副本?
  • @blackgreen 谢谢。我已经看过了,但不一样。这里的问题是,如果 proto 文件具有不同的包名称,则 protoc 不会生成指针。如果它们相同 - 这将是一个指针。
  • 但是我有很多地方需要语言,所以我决定把它移到单独的 proto 文件中。但我遇到过这种奇怪的行为
  • 我不太确定你想要达到什么目的。指针在数据交换格式中有什么好处?你基本上是想说“嘿,我要传输的数据在源机器上,在 0x...!”

标签: go protocol-buffers protoc grpc-go


【解决方案1】:

proto3 3.12 版开始,实验性支持字段存在功能,这意味着您可以再次使用optional 关键字,类似于proto2

您可以通过在生成pb.go 文件时将标志--experimental_allow_proto3_optional 传递给protoc 来实现这一点(确保您正在运行足够新版本的protocprotoc-gen-go 以支持此实验性功能)。

所以给定这个伪.proto 文件:

enum ISO639_1 {
    UNKNOWN = 0;
    zh      = 1;
}

message Video {
    string            id        = 1;
    string            title     = 2;

    optional ISO639_1 language  = 3;
    repeated ISO639_1 subtitles = 4;
}

你应该得到生成的结构体:

type Video struct {
    state         protoimpl.MessageState
    sizeCache     protoimpl.SizeCache
    unknownFields protoimpl.UnknownFields

    Language  *ISO639_1  `protobuf:"varint,3,opt,name=language,proto3,enum=grpctrace.ISO639_1,oneof" json:"language,omitempty"`
    Subtitles []ISO639_1 `protobuf:"varint,4,rep,packed,name=subtitles,proto3,enum=grpctrace.ISO639_1" json:"subtitles,omitempty"`
}

虽然这解决了您使用 language 的问题,但我不确定您是否能够绕过 repeated 字段来获取指针值。也许这个帖子可能会有所帮助 - https://stackoverflow.com/a/25637833/13183366

【讨论】:

    猜你喜欢
    • 2021-02-25
    • 2021-04-19
    • 1970-01-01
    • 1970-01-01
    • 2015-10-01
    • 2021-01-19
    • 2020-01-30
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多