I'm trying to parse this type of response from a server:
[[1,"a","b",2,"000000",[[1,2,3],[1,2,3]],"x","y","z",[[1,2,3],[1,2,3]]]]
Besides writing my own hack'ish parser for this type of messages is there a standard way to interpret this that I'm not aware of?
Your input is a JSON string. In Go, you can use the encoding/json
package to decode it.
Usually, when the structure of the JSON string is known prior, a Go struct
type can be constructed which models it, and then you can unmarshal into a value of that struct
type.
If the structure is unknown or is varying, you may unmarshal into a value of type interface{}
which can be the target of any JSON data:
s := `[[1,"a","b",2,"000000",[[1,2,3],[1,2,3]],"x","y","z",[[1,2,3],[1,2,3]]]]`
var v interface{}
if err := json.Unmarshal([]byte(s), &v); err != nil {
fmt.Println(err)
return
}
fmt.Println(v)
fmt.Printf("%#v\n", v)
Output (try it on the Go Playground):
[[1 a b 2 000000 [[1 2 3] [1 2 3]] x y z [[1 2 3] [1 2 3]]]]
[]interface {}{[]interface {}{1, "a", "b", 2, "000000", []interface {}{[]interface {}{1, 2, 3}, []interface {}{1, 2, 3}}, "x", "y", "z", []interface {}{[]interface {}{1, 2, 3}, []interface {}{1, 2, 3}}}}
As you can see, the result is a slice of slices, with elements of varying types (JSON numbers, strings and even more slices).
Here's the same output adding indentation to get a better feeling of it (using Go's composite literal syntax):
[]interface{}{
[]interface{}{
1, "a", "b", 2, "000000",
[]interface{}{
[]interface{}{1, 2, 3},
[]interface{}{1, 2, 3}},
"x", "y", "z",
[]interface{}{
[]interface{}{1, 2, 3},
[]interface{}{1, 2, 3},
},
},
}
Of course this is not very convenient, as you have to use type assertion to "extract" values from this "generic" value of type interface{}
, for example to extract the first 2 non-arrays values (also printing their types for verification):
fmt.Printf("%T %[1]v\n", v.([]interface{})[0].([]interface{})[0])
fmt.Printf("%T %[1]v\n", v.([]interface{})[0].([]interface{})[1])
Output:
float64 1
string a
Worth noting that JSON numbers in Go are unmarshaled to a value of type float64
even though they could be integers (unless another type is explicitly specified).