Golang:“ JSON:不能将其列入类型字符串的GO值”。

发布于 2025-02-11 20:25:17 字数 835 浏览 0 评论 0原文

我有一个Protobuf消息,

message Event {
   string type = 1;
   string names = 2;
}

“名称”的类型最近从String转换为[] String在基础数据源中,旧数据仍然是字符串,但新数据是将成为[]字符串。 因此,当返回数据时,某些记录可以具有字符串,其余的可以具有[]字符串。 我需要自定义删除(jsonpb.unmarshaler,都用于将json.rawmessage unmarshal json.rawmessage转换为事件类型),并将“名称”转换为字符串,如果是[]字符串(通过将阵列中的值串联到序列)到保持响应格式一致,以使客户不会破裂。

我在解散时会遇到此错误:

json:不能将字符串

的go值汇总到go中

,请任何人建议如何做到这一点?

我尝试过Google.protobuf。任何类似的人,但无法完全弄清楚透明的部分。

message Event {
   string type = 1;
   google.protobuf.Any names = 2;
}

Unmarshall片段:

evnt := new(pb.Event)
unmarshaler    = jsonpb.Unmarshaler{AllowUnknownFields: true}
unmarshaler.Unmarshal(bytes.NewReader(*<json.RawMessage>*), evnt)

I have a protobuf message

message Event {
   string type = 1;
   string names = 2;
}

The type for ‘names’ has recently changed from string to []string in the underlying data source where older data is still a string but new data is going to be []string.
So, when the data is returned, some records can have string and the rest can have []string.
I need to customize the unmarshaling (jsonpb.Unmarshaler is being used to unmarshal json.Rawmessage to Event type) and convert the ‘names’ to a string if it’s an []string (by concatenating the values from array/slice) in order to keep the response format consistent so client doesn't break.

I get this error while unmarshaling:

json: cannot unmarshal array into Go value of type string

Can anyone please suggest on how this can be done?

I tried google.protobuf.Any like below but couldn’t completely figure the unmarshaling part.

message Event {
   string type = 1;
   google.protobuf.Any names = 2;
}

Unmarshall snippet:

evnt := new(pb.Event)
unmarshaler    = jsonpb.Unmarshaler{AllowUnknownFields: true}
unmarshaler.Unmarshal(bytes.NewReader(*<json.RawMessage>*), evnt)

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

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

发布评论

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

评论(1

紫竹語嫣☆ 2025-02-18 20:25:17

将名称制成类型,然后给它一个自定义umarshaljson方法。示例:

package main

import (
    "encoding/json"
    "fmt"
    "os"
    "strings"
)

type name struct {
    New []string
    Old string
}

type event struct {
    Type string `json:"type"`
    Name name   `json:"name"`
}

func do(j string) {
    var e event
    err := json.Unmarshal([]byte(j), &e)
    if err != nil {
        fmt.Fprintf(os.Stderr, "Failed to unmarshall %s: %s\n", j, err)
        return
    }
    fmt.Printf("%v\n", e)
}

func (n *name) UnmarshalJSON(text []byte) error {
    t := strings.TrimSpace(string(text))
    if strings.HasPrefix(t, "[") {
        return json.Unmarshal(text, &n.New)
    }
    return json.Unmarshal(text, &n.Old)
}

func main() {
    jsonstring := `{"type":"a","name":"rodney"}`
    jsonarray := `{"type":"a","name":["rodney","dangerfield"]}`
    do(jsonstring)
    do(jsonarray)
}

游乐场: https://go.dev/play/pplay/p/sntuzkhc_rt

Make the name into a type then give it a custom UnmarshalJSON method. Example:

package main

import (
    "encoding/json"
    "fmt"
    "os"
    "strings"
)

type name struct {
    New []string
    Old string
}

type event struct {
    Type string `json:"type"`
    Name name   `json:"name"`
}

func do(j string) {
    var e event
    err := json.Unmarshal([]byte(j), &e)
    if err != nil {
        fmt.Fprintf(os.Stderr, "Failed to unmarshall %s: %s\n", j, err)
        return
    }
    fmt.Printf("%v\n", e)
}

func (n *name) UnmarshalJSON(text []byte) error {
    t := strings.TrimSpace(string(text))
    if strings.HasPrefix(t, "[") {
        return json.Unmarshal(text, &n.New)
    }
    return json.Unmarshal(text, &n.Old)
}

func main() {
    jsonstring := `{"type":"a","name":"rodney"}`
    jsonarray := `{"type":"a","name":["rodney","dangerfield"]}`
    do(jsonstring)
    do(jsonarray)
}

Playground: https://go.dev/play/p/sNtUZKHC_Rt

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