json.Unmarshal将嵌套对象转换为字符串或[]字节

时间:2013-11-20 16:52:17

标签: json go unmarshalling

我正在尝试解组一些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

4 个答案:

答案 0 :(得分:27)

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

文档说明:

  

输入RawMessage [] byte

     

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

答案 1 :(得分:3)

Foo类型是map [string]字符串,因此请正确定义Foo:

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

认为这会更好用

答案 2 :(得分:2)

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

type Prefs []byte

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

playground demo

答案 3 :(得分:-1)

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

如果你运行它,你会发现类型转换切片和编组切片之间的[]字节在'Prefs'变量的点附近不同。

json从struct

编组

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

typecast [] byte

[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包无法识别的内容。