简体   繁体   中英

Json decode/unmarshal in golang

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}]}

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}]}

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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