在Go中表示此JSON的最佳方法是什么?
我正在编写一个端点以返回Geckoboard的数据,它不包括以下格式:在Go中表示此JSON的最佳方法是什么?,json,go,geckoboard,Json,Go,Geckoboard,我正在编写一个端点以返回Geckoboard的数据,它不包括以下格式: { "item": [ { "value": "274057" }, [ "38594", "39957", "35316", "35913", "36668", "45660", "41949" ] ] } “item”是各种结构的数组。我将如何在Go中表示这些数据 注意:这不是关于我如
{
"item": [
{
"value": "274057"
},
[
"38594",
"39957",
"35316",
"35913",
"36668",
"45660",
"41949"
]
]
}
“item”
是各种结构的数组。我将如何在Go中表示这些数据
注意:这不是关于我如何解组的问题,我需要生成这种格式。这比你想象的要简单。对于普通读者来说,它只是没有那么好的文档记录。我推荐
ffjson
而不是普通的json
tho。它是以这样一种方式组成的,除了库名称之外,您不需要更改语法
这很简单:
type User struct {
Id int `json:'id'`
Name string `json:name`
SomeId1 int `json:some_id_1`
SomeId2 int `json:some_id_2`
SomeId3 int `json:some_id_3`
SomeId4 int `json:some_id_4`
}
item := map[string]User{}
for i := 0; i < 10; i++ {
item[strconv.itoa(i)] = User{i, "Username X", 38393, 29384, 12393, 123981}
}
buf, err := ffjson.Marshal(&item)
类型用户结构{
Id int`json:'Id'`
Name字符串`json:Name`
SomeId1 int`json:some\u id\u 1`
SomeId2 int`json:some_id_2`
SomeId3 int`json:some\u id\u 3`
SomeId4 int`json:some_id_4`
}
项:=映射[字符串]用户{}
对于i:=0;i<10;i++{
项目[strconv.itoa(i)]=用户{i,“用户名X”,38393,29384,12393,123981}
}
buf,err:=ffjson.Marshal(&item)
结构的缺点(即使在
ffjson
still中)是总是使用reflection
,这在需要高性能的时候会浪费大量的CPU周期ffjson
比普通的json
快2-3倍,当您将其保存到地图时。通过这种方式,库可以编译您封送并重新使用的每个数据结构,而不是使用reflect
不断检查数据完整性/结构。有一种简单的方法可以创建一些数据结构的值,您知道要生成/复制的JSON输出:
获取要生成的输出,并将其解组到map[string]接口{}
中。您将获得一个映射值,当您封送时,该值将产生所需的输出。当您解组预期输出时,您可以检查结果映射值,以了解需要为预期输出创建什么
这在你的情况下也适用。代码如下:
var m map[string]interface{}
err := json.Unmarshal([]byte(input), &m)
if err != nil {
panic(err)
}
fmt.Printf("%+v\n", m)
res, err := json.MarshalIndent(m, "", " ")
if err != nil {
panic(err)
}
fmt.Println(string(res))
其中,input
是您的JSON输入:
const input = `{
"item": [
{
"value": "274057"
},
[
"38594",
"39957",
"35316",
"35913",
"36668",
"45660",
"41949"
]
]
}`
此程序生成与所需输出(或输入)相同的输出:
在上尝试完整的应用程序
分析取消编组的贴图值:
显然,它有一个键“item”
,其值的类型:
fmt.Printf("%T\n", m["item"]); // Prints []interface{}
所以这是一片。它有两个值,它们的类型是:
fmt.Printf("%T\n", m["item"].([]interface{})[0]); // map[string]interface{}
fmt.Printf("%T\n", m["item"].([]interface{})[1]); // []interface{}
因此,切片包含2个值:
- 映射(值“
对)”:“274057”
- 和另一个片段(ID或编号列表)
m := map[string]interface{}{
"item": []interface{}{
map[string]interface{}{"value": "274057"},
[]interface{}{"38594", "39957", "35316", "35913", "36668", "45660", "41949"},
},
}
封送会产生相同的JSON输出。可能的重复我需要做相反的事情,封送它(以及我将如何组织它),可能的重复仍然相关吗?你可能是指数据结构。我对每个深度使用
map[string]接口{}
,对每个条目使用map[string]string
。希望这能帮到你。请使用ffjson
。原生的json
仍然非常慢。是的,基本原理仍然是一样的。在Go中表示数据的最简单方法是struct{Item[]interface{}
。如果你需要的话,我可以用一个例子来补充答案。如果没有必要的话,请避免使用结构。当你真的想要性能,让马歇尔的反映出来时,你的速度会非常慢。只是说:)那真的很有帮助,谢谢。我想使用映射的一个折衷办法是代码的可读性会受到一些影响。我们的应用程序不是性能关键型的,所以结构的使用不是一个太大的问题。但感谢您的洞察力,我相信这一点有一天会派上用场的!:)<代码>字符串(i)
没有达到我认为你想要的效果。哈哈,谢谢,修复了:)那会是一些邪恶的字节^^
m := map[string]interface{}{
"item": []interface{}{
map[string]interface{}{"value": "274057"},
[]interface{}{"38594", "39957", "35316", "35913", "36668", "45660", "41949"},
},
}