【问题标题】:How to fix json: cannot unmarshal object into Go value of type []json.RawMessage如何修复 json:无法将对象解组为 []json.RawMessage 类型的 Go 值
【发布时间】:2021-05-20 03:17:41
【问题描述】:

我想解组

var j = []byte(`[{"major":1},{"minor":0}]`)

进入

type Version struct {
    Major int `json:"major"`
    Minor int `json:"minor"`
}

通过循环内部切片使用自定义解组器:

func (h *Version) UnmarshalJSON(b []byte) error {
    var wrapper []json.RawMessage

    err := json.Unmarshal(b, &wrapper)
    if err == nil {
        for _, v := range wrapper {
            if err = json.Unmarshal(v, &h); err != nil {
                break
            }
        }
    }

    return err
}

内部UnmarshalJSON 触发器

json: cannot unmarshal object into Go value of type []json.RawMessage

这很奇怪,因为目标是*Version。这里有什么问题?播放:https://play.golang.org/p/Av59IkYTioS

【问题讨论】:

  • 你调用 json.Unmarshal(v, h) 来调用 Version.UnmarshalJSON。你根本不能这样做。你要么需要一个辅助类型,要么重新设计。
  • 替代品1, 2 如果您可以依赖数组中对象的顺序和数量。

标签: json go struct slice


【解决方案1】:

“内部”解组调用将递归调用Version.UnmarshalJSON()

json.Unmarshal(v, &h)

您的错误来自递归调用:您尝试将{"major":1} 解组为[]json.RawMessage

你不想递归调用Version.UnmarshalJSON(),所以创建一个新的类型来剥离所有方法,包括UnmarshalJSON()

    type version Version
    h2 := (*version)(h)
    for _, v := range wrapper {
        if err = json.Unmarshal(v, &h2); err != nil {
            break
        }
    }

通过此更改它可以工作,并且添加 fmt.Println(msg) 输出将是(在 Go Playground 上尝试):

<nil>
{1 0}

通常这会导致堆栈溢出错误,但由于您的第二次调用错误,递归中断。见相关:Call json.Unmarshal inside UnmarshalJSON function without causing stack overflow

【讨论】:

    猜你喜欢
    • 2017-01-06
    • 1970-01-01
    • 2021-03-05
    • 2018-05-06
    • 2020-04-01
    • 1970-01-01
    • 2020-04-29
    • 2018-05-23
    • 2022-01-12
    相关资源
    最近更新 更多