Json decode/unmarshal in golang

huangapple go评论85阅读模式
英文:

Json decode/unmarshal in golang

问题

我有以下的 JSON 数据:

{"results":
    [{"columns":["room_id","player_name","player_ip"],
      "types":["integer","text","text"],
      "values":[[1,"alice","127.0.0.1"],
                [1,"bob","127.0.0.1"]],
      "time":0.00018839100000000002}]}

其中的 values 可以有任意数量的元素 []。当我尝试将 JSON 解析为结构体时,values 标签没有被正确解析。

结构体如下:

type queryResults struct {
    Results []struct {
        Columns []string `json:"columns"`
        Types []string `json:"types"`
        Values []struct {
            Room_id int
            Player_name string
            Player_ip string
        } `json:"values"`
        Time float64 `json:"time"`
    } `json:"results"`
}

代码如下:

// jsonString 是要解析的字符串输入
resultjson := queryResults{}
json.Unmarshal([]byte(jsonString), &resultjson)
fmt.Printf("%+v", resultjson)

当前输出:

{Results:
    [{Columns:[room_id player_name player_ip]
      Types:[integer text text]
      Values:[{room_id:0 player_name: player_ip:}
              {room_id:0 player_name: player_ip:}]
      Time:0.00018839100000000002}]}

期望输出:

{Results:
    [{Columns:[room_id player_name player_ip]
      Types:[integer text text]
      Values:[{room_id:1 player_name:alice player_ip:127.0.0.1}
              {room_id:1 player_name:bob player_ip:127.0.0.1}]
      Time:0.00018839100000000002}]}
英文:

I have the following json:

{"results":
[{"columns":["room_id","player_name","player_ip"],
  "types":["integer","text","text"],
  "values":[[1,"alice","127.0.0.1"]
            [1,"bob","127.0.0.1"]],
  "time":0.00018839100000000002}]}

where values can have any number of elements [] inside them. When i try to unmarshal the json into a struct, the "values" tag does not get parsed properly

struct:

type queryResults struct {
    	Results []struct {
    		Columns []string `json:"columns"`
    		Types []string `json:"types"`
    		Values []struct {
    			Room_id int
    			Player_name string
    			Player_ip string
    		} `json:"values"`
    		Time float64 `json:"time"`
    	} `json:"results"`
    }

Code:

//jsonString is the string input to Unmarshal
resultjson := queryResults{}
json.Unmarshal([]byte(jsonString), &resultjson)
fmt.Printf("%+v",resultjson)

Current Output:

{Results:
 [{Columns:[room_id player_name player_ip] 
   Types:[integer text text] 
   Values:[{room_id:0 player_name: player_ip:} 
           {room_id:0 player_name: player_ip:}] 
   Time:0.00018839100000000002}]}

Expected Output:

{Results:
     [{Columns:[room_id player_name player_ip] 
       Types:[integer text text] 
       Values:[{room_id:1 player_name:alice player_ip:127.0.0.1} 
               {room_id:1 player_name:bob player_ip:127.0.0.1}] 
       Time:0.00018839100000000002}]}

答案1

得分: 2

问题在于你的结构定义期望 "values" 包含一个对象数组,但实际的 JSON 包含一个数组的数组。如果你检查 json.Unmarshal() 的结果,你会看到它报告了一个关于这个问题的错误。在 golang playground 上尝试一下。

错误信息:json: 无法将数组解组为类型为 struct { Room_id int; Player_name string; Player_ip string } 的 Go 值

据我所知,你不能直接将其映射到结构体中,你需要将其读入一个数组,然后对其进行后处理以得到最终的类型。这里有一个示例,成功解析了 JSON(后处理转换留给读者自行完成)。

{Results:[{Columns:[room_id player_name player_ip] 
          Types:[integer text text] 
          Values:[[1 alice 127.0.0.1] [1 bob 127.0.0.1]]
          Time:0.00018839100000000002}]}
英文:

The problem is that your struct definition expects "values" to contain an array of objects, but your actual json contains an array of arrays. If you check the result of json.Unmarshal() you'll see it reports an error about this. try on golang playground

error json: cannot unmarshal array into Go value of type struct { Room_id int; Player_name string; Player_ip string }

As far as i know you can't map this directly into the struct, you'd need to read it into an array then post process it into your final type. Here's an example that successfully parses the json [the post parsing conversion is left as an exercise for the reader]

{Results:[{Columns:[room_id player_name player_ip] 
          Types:[integer text text] 
          Values:[[1 alice 127.0.0.1] [1 bob 127.0.0.1]]
          Time:0.00018839100000000002}]}

答案2

得分: 2

Json数组应该解组为Go切片或数组。看起来你正在尝试将values中的数组解组为一个struct

"values": [[1,"alice","127.0.0.1"], [1,"bob","127.0.0.1"]]

上面的数组应该解组为一个Go切片的切片。

尝试使用以下代码:

type queryResults struct {
    Results []struct {
        Columns []string `json:"columns"`
        Types   []string `json:"types"`
        Values  [][]interface{} `json:"values"`
        Time    float64 `json:"time"`
    } `json:"results"`
}

Go Playground中尝试运行。

并且不要忽略错误。如果你尝试了以下代码:

err := json.Unmarshal([]byte(jsonString), &resultjson)
if err != nil {
    fmt.Println(err)
}

你就可以看到错误信息了。

英文:

Json arrays should be unmarshalled into Go slices or arrays. Looks like you are trying to unmarshal the arrays inside values to a struct

"values": [[1,"alice","127.0.0.1"], [1,"bob","127.0.0.1"]]

Above array of arrays should be unmarshalled into a Go slice of slices.

try,

type queryResults struct {
	Results []struct {
		Columns []string `json:"columns"`
		Types   []string `json:"types"`
		Values  [][]interface{} `json:"values"`
		Time float64 `json:"time"`
	} `json:"results"`
}

in Go Playground

And don't ignore errors. If you tried,

err := json.Unmarshal([]byte(jsonString), &resultjson)
if(err != nil){
    fmt.Println(err)
}

you could have seen the error.

huangapple
  • 本文由 发表于 2016年4月7日 13:09:51
  • 转载请务必保留本文链接:https://go.coder-hub.com/36467158.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定