Suk*_*esh 9 json go protocol-buffers protobuf-go
如何在Golang中使用protojson包实现以下功能?
协议缓冲区:
type ProtoResp struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Xesp isActionResponse_Xesp `protobuf_oneof:"xesp"`
TimeTakena string `protobuf:"bytes,9,opt,name=time_takena,json=timeTakena,proto3" json:"time_takena,omitempty"`
}
Run Code Online (Sandbox Code Playgroud)
因此,我需要将 proto 数组编组为 json。例如,
type ProtoResp struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Xesp isActionResponse_Xesp `protobuf_oneof:"xesp"`
TimeTakena string `protobuf:"bytes,9,opt,name=time_takena,json=timeTakena,proto3" json:"time_takena,omitempty"`
}
Run Code Online (Sandbox Code Playgroud)
我该如何整理这个protoResps?
目前,protojson.Marshal函数可以封送ProtoResp,但不能封送[]ProtoResp作为其原型片段。
我还需要稍后将其解组回[]ProtoResp
提前致谢。
我想这json.Marshal(protoResps)对你不起作用,因为该文件protojson规定:
该包产生的输出与标准“encoding/json”包不同,后者无法在协议缓冲区消息上正确运行。
一种解决方法仍然是使用encoding/json,但用 pakcage 编组/解组每个项目protojson。
json.Marshaler并json.Unmarshaler如果ProtoResp是本地类型,则修改它以实现Marshaler和Unmarshaler接口:
import (
"google.golang.org/protobuf/encoding/protojson"
)
func (r *ProtoResp) MarshalJSON() ([]byte, error) {
return protojson.Marshal(r)
}
func (r *ProtoResp) UnmarshalJSON(data []byte) error {
return protojson.Unmarshal(data, r)
}
Run Code Online (Sandbox Code Playgroud)
然后就可以安全地使用encoding/json包来编组/解组[]*ProtoResp(不应该复制 的实例ProtoResp,大多数时候,您想要保存一个指针。*ProtoResp从现在开始我将使用)。
json.RawMessage延迟编码/解码如果ProtoResp不是本地类型,解决方法是使用json.RawMessage延迟编码/解码。这种方法会消耗更多的内存。
import (
"encoding/json"
"google.golang.org/protobuf/encoding/protojson"
)
func Marshal(protoResps []*ProtoResp) ([]byte, error) {
raw := make([]json.RawMessage, len(protoResps))
for i, p := range protoResps {
r, err := protojson.Marshal(p)
if err != nil {
return nil, err
}
raw[i] = r
}
return json.Marshal(raw)
}
func Unmarshal(data []byte) ([]*ProtoResp, error) {
var raw []json.RawMessage
if err := json.Unmarshal(data, &raw); err != nil {
return nil, err
}
protoResps := make([]*ProtoResp, len(raw))
for i, r := range raw {
p := &ProtoResp{}
if err := protojson.Unmarshal(r, p); err != nil {
return nil, err
}
protoResps[i] = p
}
return protoResps, nil
}
Run Code Online (Sandbox Code Playgroud)