我遇到了Protoc和我现有的包含可为空字符串字段的结构的问题。
我要序列化以进行传输的结构包含一堆在json中可为空的字段(因此我们可以区分null
,""
和设置值)。
type Message struct {
Path *string `json:"path"`
}
因此,如果用户发送一个空的json字符串{}
,则路径将为nil
而不是""
,而{"path":""}
也是有效的,并且与{{ 1}}。
我想出的{"path": null}
声明显然是这样的(并且是可选的,因为proto3
和required
从proto3中删除了:
optional
运行Protoc之后,我得到的结构看起来像这样,所有值均为syntax = "proto3";
message Message {
string Path = 1;
}
,无法将它们声明为string
:
*string
很显然,我无法从现有结构中分配此数组。但是,即使我要使用适当的空指针检查用type Message struct {
Path string `protobuf:"bytes,1,opt,name=Path,proto3" json:"Path,omitempty"`
}
编写乏味的映射代码,也要放弃源代码结构(target.Path = *source.Path
,nil
,{{ 1}})。
关于如何继续进行操作或是否对Go Protobuf进行了扩展的任何建议?还是会去描述这个原始声明?
答案 0 :(得分:1)
Proto3返回Zero Value,即使未设置字段也是如此。当前,无法区分是否已设置字段。
请参阅Github问题#15。
可能的解决方案:
google.protobuf.FieldMask
扩展名,请参阅常见设计模式
来自Google API设计指南:Partial Responses和Output Fields。可能不是解决方案:
使用target.Path = * source.Path和适当的空指针编写乏味的映射代码。
...,因为这不适用于零值为0的int类型。
答案 1 :(得分:0)
对于我来说,我通过几个软件包解决了这个问题:
我的原始文件如下:
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"`
}
答案 2 :(得分:0)
https://stackoverflow.com/a/62566052
proto3 支持可选,带有标志 --experimental_allow_proto3_optional