简体   繁体   English

json.Unmarshal 嵌套对象成字符串或 []byte

[英]json.Unmarshal nested object into string or []byte

I'm trying to Unmarshal some json so that a nested object does not get parsed but just treated as a string or []byte .我正在尝试解组一些 json,以便嵌套对象不会被解析,而只是被视为string[]byte

So I want to get the following:所以我想得到以下信息:

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

Unmarshaled into:解组为:

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

I get the following error:我收到以下错误:

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

playground demo游乐场演示

I think what you are looking for is the RawMessage type in the encoding/json package.我认为您正在寻找的是encoding/json包中的RawMessage类型。

The documentation states:该文档指出:

type RawMessage []byte输入 RawMessage [] 字节

RawMessage is a raw encoded JSON object. RawMessage 是一个原始编码的 JSON 对象。 It implements Marshaler and Unmarshaler and can be used to delay JSON decoding or precompute a JSON encoding.它实现了 Marshaler 和 Unmarshaler,可用于延迟 JSON 解码或预计算 JSON 编码。

Here is a working example of using RawMessage:这是一个使用 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)
}

Output:输出:

{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]} {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操场

The Foo type is a map[string]string so define Foo correctly: Foo 类型是 map[string]string 所以正确定义 Foo :

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

Think that would work better认为这样会更好

Defining a type which implements the Unmarshaler interface gives you access to the []byte 's being parsed.定义实现Unmarshaler接口的类型使您可以访问正在解析的[]byte

type Prefs []byte

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

playground demo游乐场演示

After a bit of tinkering I've found that in your playground demo the biggest problem is the typecasting of the json to a []byte.经过一番修补后,我发现在您的游乐场演示中,最大的问题是将 json 类型转换为 []byte。 To see what I mean by that, take a look a this playground: http://play.golang.org/p/M0706KCZbh要了解我的意思,请看一下这个游乐场: http ://play.golang.org/p/M0706KCZbh

If you run it, you'll notice the []byte between the typecast slice and the marshaled slice differ around the point of the 'Prefs' variable.如果你运行它,你会注意到 typecast slice 和 marshaled slice 之间的 []byte 在 'Prefs' 变量的点附近不同。

json marshaled from struct从结构封送的 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 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... [123 34 105 100 34 58 49 53 44 34 112 114 101 102 115 34 58 123 34 102 111 111 34...

I've removed white space to try and make it line up as much as possible.我已经删除了空白以尝试使其尽可能对齐。 The main takeaway from this is that typecasting does not produce the same results as running the data through the json.Marshal method and to make this work you would need a custom type to handle the unmarshaling of what the json package does not recognize.主要的收获是,类型转换不会产生与通过 json.Marshal 方法运行数据相同的结果,并且要使这项工作正常工作,您需要一个自定义类型来处理 json 包无法识别的内容的解组。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM