Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/bash/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在Go中表示此JSON的最佳方法是什么?_Json_Go_Geckoboard - Fatal编程技术网

在Go中表示此JSON的最佳方法是什么?

在Go中表示此JSON的最佳方法是什么?,json,go,geckoboard,Json,Go,Geckoboard,我正在编写一个端点以返回Geckoboard的数据,它不包括以下格式: { "item": [ { "value": "274057" }, [ "38594", "39957", "35316", "35913", "36668", "45660", "41949" ] ] } “item”是各种结构的数组。我将如何在Go中表示这些数据 注意:这不是关于我如

我正在编写一个端点以返回Geckoboard的数据,它不包括以下格式:

{
  "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或编号列表)
以下是复制相同贴图值的Go代码:

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"},
    },
}