【问题标题】:json.Unmarshal nested object into string or []bytejson.Unmarshal 嵌套对象成字符串或 []byte
【发布时间】:2013-12-04 19:12:53
【问题描述】:

我正在尝试解组一些 json,以便嵌套对象不会被解析,而只是被视为 string[]byte

所以我想得到以下内容:

{
    "id"  : 15,
    "foo" : { "foo": 123, "bar": "baz" }
}

解组为:

type Bar struct {
    ID  int64  `json:"id"`
    Foo []byte `json:"foo"`
}

我收到以下错误:

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

playground demo

【问题讨论】:

  • 为什么不使用map[string]interface{}?它还具有以正确方式重新编组的优点。
  • @JamesHolmes 通常不建议这样做,因为这允许任何类型,如果您不明确希望支持所有类型,请不要使用空接口(接口{}),它会导致您比它解决的问题更多

标签: json go unmarshalling


【解决方案1】:

我认为您正在寻找的是 RawMessage 包中的 encoding/json 类型。

文档说明:

输入 RawMessage []字节

RawMessage 是一个原始编码的 JSON 对象。它实现了 Marshaler 和 Unmarshaler,可用于延迟 JSON 解码或预计算 JSON 编码。

这是一个使用 RawMessage 的工作示例:

package main

import (
    "encoding/json"
    "fmt"
)

var jsonStr = []byte(`{
    "id"  : 15,
    "foo" : { "foo": 123, "bar": "baz" }
}`)

type Bar struct {
    Id  int64           `json:"id"`
    Foo json.RawMessage `json:"foo"`
}

func main() {
    var bar Bar

    err := json.Unmarshal(jsonStr, &bar)
    if err != nil {
        panic(err)
    }
    fmt.Printf("%+v\n", bar)
}

输出:

{Id:15 Foo:[123 32 34 102 111 111 34 58 32 49 50 51 44 32 34 98 97 114 34 58 32 34 98 97 122 34 32 125]}

Playground

【讨论】:

  • 这正是我想要的
  • 告诉过你 ;) 。很高兴为您提供帮助!
  • 我得到了那个输出,但是我该如何使用它呢?
【解决方案2】:

Foo 类型是一个 map[string]string,所以正确定义 Foo:

type Bar struct {
    id int64
    Foo map[string]string
}

觉得这样会更好

【讨论】:

  • 所以[]bytes -> Unmarshal -> map[string]interface{} -> Marshal -> string ... 为什么?
【解决方案3】:

定义实现Unmarshaler 接口的类型使您可以访问正在解析的[]byte

type Prefs []byte

func (p *Prefs) UnmarshalJSON(b []byte) error {
    *p = make(Prefs, len(b))
    copy(*p, b)
    return nil
}

playground demo

【讨论】:

    【解决方案4】:

    经过一番修改后,我发现在您的游乐场演示中,最大的问题是将 json 类型转换为 []byte。要了解我的意思,请看一下这个游乐场:http://play.golang.org/p/M0706KCZbh

    如果你运行它,你会注意到 typecast slice 和 marshaled slice 之间的 []byte 在 'Prefs' 变量的点附近不同。

    从结构封送的json

    [123 34 105 100 34 58 49 53 44 34 112 114 101 102 115 34 58 34 101 121 65 105 90...

    类型转换 []字节

    [123 34 105 100 34 58 49 53 44 34 112 114 101 102 115 34 58 123 34 102 111 111 34...

    我已经删除了空白以尝试使其尽可能对齐。主要的收获是,类型转换不会产生与通过 json.Marshal 方法运行数据相同的结果,并且要使这项工作正常工作,您需要一个自定义类型来处理 json 包无法识别的内容的解组。

    【讨论】:

    猜你喜欢
    • 2019-07-21
    • 1970-01-01
    • 1970-01-01
    • 2011-11-30
    • 2021-06-24
    • 2015-12-23
    • 2023-01-16
    • 2022-01-08
    • 1970-01-01
    相关资源
    最近更新 更多