如何将原始的元素元帅到Golang的JSON?

发布于 2025-02-01 05:04:29 字数 734 浏览 3 评论 0原文

如何使用Golang的Protojson软件包来实现以下内容?

Protobuf:

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"`
}

所以,我需要将原始阵列元组纳入JSON。例如,

var protoResps []ProtoResp

我如何元使用此protoresps

当前,protojson.marshal函数可以元帅protoresp,但不能元帅[] Protoresp作为其proto的切片。

我还需要稍后将其汇总到[] Protoresp之前,

请提前。

How to achieve the following with protojson package in Golang?

Protobuf:

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"`
}

So, I need to marshal the array of proto into a json. For example,

var protoResps []ProtoResp

How do I marshal this protoResps?

Currently, protojson.Marshal function can marshal ProtoResp but can't marshal []ProtoResp as its slice of proto.

I also need to unmarshal this later back into []ProtoResp

Thanks in advance.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

自此以后,行同陌路 2025-02-08 05:04:29

我猜json.marshal(protoresps)对您不起作用,因为protojson的文档状态:

此软件包与标准“编码/JSON”软件包产生不同的输出,该软件包无法在协议缓冲区消息上正确操作。

一个解决方法仍然是使用编码/json,但是使用protojson pakcage元帅/删除每个项目。

选项1:实现json.marshalerjson.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)
}

然后,使用编码/json package to Marshal/unmarshal []代码> protoresp不应复制,大多数情况下,您要握住指针。

则延迟编码/解码

选项2:使用json.rawmessage如果protoresp不是本地类型, 延迟编码/解码。这种方法会消耗更多的内存。

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
}

I guess json.Marshal(protoResps) does not work for you because the document for protojson states:

This package produces a different output than the standard "encoding/json" package, which does not operate correctly on protocol buffer messages.

One workaround is still to utilize the encoding/json, but marshal/unmarshal each item with the protojson pakcage.

Option 1: Implement json.Marshaler and json.Unmarshaler

If ProtoResp is a local type, modify it to implement the Marshaler and Unmarshaler interfaces:

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)
}

Then it's safe to use the encoding/json package to marshal/unmarshal []*ProtoResp (an instance of ProtoResp should not be copied, most of the time, you want to hold a pointer instead. I will use *ProtoResp from now on).

Option 2: Use json.RawMessage to delay the encoding/decoding

If ProtoResp is not a local type, a workaround is to use json.RawMessage to delay the encoding/decoding. This approach consumes more memory.

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
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文