如何在Golang中解封嵌套的JSON

时间:2018-04-10 05:53:58

标签: json go

我有一些JSON,我希望在Go中解组。 JSON字典的顶级键之一具有可解析的JSON值。例如:

{ 
    "Name": "Tony",
    "Age": 50,
    "Extra": {\"Weight\":180}
}

我有一个我想要解组的相应结构:

type Person struct {
    Name string
    Age int
    Extra []byte
 }

我希望Extra键是一个字节数组,因为JSON结构会有所不同,并且它的结构对于正在编写的程序并不重要。程序只需要将这些数据作为字节数组向下推送。

如何诱导Go JSON编码器像这样处理extra的值?

2 个答案:

答案 0 :(得分:1)

您有两种选择:

使用json.RawMessage

在这里你必须稍微改变你的结构:

type Person struct {
    Name string
    Age int
    Extra *json.RawMessage
}

然后,你可以像往常一样Unmarshal

person := Person{}
err := json.Unmarshal(raw_bytes, &person)
// handle err

最后,你可以再次解组Extra,你甚至可以在它上面做一些断言类型来预先检测类型

var extra_option_1 string
extra_option_2 := AnotherStruct{}

err := json.Unmarshal(raw_bytes, &extra_option_1)
// handle err

// or

err := json.Unmarshal(raw_bytes, &extra_option_2)
// handle err

使用map[string]interface{}{} - 老实说在你的情况下不那么有用

您可以使用常规map[string]interface{}{}直接解组“未知”或动态有效负载 但是我不鼓励这种用法,因为速度较慢,你应该总是知道会发生什么。

无论如何,以下是伪代码:

payload := map[string]interface{}{}
err := json.Unmarshal(raw_bytes, &payload)
// handle err

在最后一种情况下,您甚至需要对每个字段进行断言。

答案 1 :(得分:0)

使用json.RawMessageinterface{}

type Person struct {
    Name string
    Age int
    Extra json.RawMessage
}

type Person struct {
    Name string
    Age int
    Extra interface{}
}

使用json.RawMessage,数据作为一个字节切片向下推。使用interface{},数据将被解组为Go值(bool,float64,string,[] interface {},map [string] interface {},nil)并封送回JSON。两个选项都通过应用程序传递任意JSON。如果应用程序没有理由使用其中一个,那么json.RawMessage可能是更好的选择,因为它更快。