Go Protobuf声明和Go结构体中的可选字段(字符串指针)

8

我在使用Protoc时遇到了问题,因为我的现有结构包含可为空的字符串字段。

我正在尝试序列化要传输的结构,其中包含许多在json中可为空的字段(这样我们可以区分null""和一个已设置的值)。

type Message struct {
  Path *string `json:"path"`
}

如果用户发送空的JSON字符串{},则路径将为nil而不是"",而{"path":""}也是有效的,并且与{"path": null}不同。
我提出的proto3声明显然如下(并且作为可选项,requiredoptional被从proto3中删除了):
syntax = "proto3";
message Message {
  string Path = 1;
}

在运行 Protoc 之后,我得到了一个结构体,它看起来像这样,所有的值都是 string,无法将其声明为 *string
type Message struct {
  Path string `protobuf:"bytes,1,opt,name=Path,proto3" json:"Path,omitempty"`
}

显然,我不能从现有的结构中分配给这个数组。但即使我写了繁琐的映射代码,并使用适当的空指针检查来编写 target.Path = *source.Path,我也会失去源结构的三重含义(nil"""value")。
您有什么建议或者是否有Go Protobuf扩展可以解决这个问题?或者如何描述这个proto声明呢?
3个回答

7

Proto3即使某个字段未设置,也会返回零值。目前还没有办法区分是否设置了字段。

请参阅Github问题#15

可能的解决方法:

  • 改用proto2而不是proto3
  • 使用nullable扩展。
  • 使用google.protobuf.FieldMask扩展,请参阅Google API设计指南中的常见设计模式:部分响应输出字段

1

0
在我的情况下,我使用了几个包来解决这个问题:
  1. https://github.com/gogo/protobuf
  2. https://github.com/golang/protobuf

我的proto文件长这样:

syntax = "proto3";

import "google/protobuf/wrappers.proto";
import "github.com/gogo/protobuf/gogoproto/gogo.proto";

message Message {
  google.protobuf.StringValue path = 1 [(gogoproto.wktpointer) = true];
}

生成 Go 代码的命令,我使用的是这个样子:

protoc -I. -I%GOPATH%/src --gogofaster_out=plugins=grpc:. proto/*.proto

生成的 Go 文件长这样:
type Message struct {
    Path *string `protobuf:"bytes,1,opt,name=path,json=path,proto3,wktptr" json:"path,omitempty"`
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接