I'm RTFMing, specifically the section on Decoding Arbitrary Go Data. Based on that section, I've written the following test program
var f interface{}
json.Unmarshal(
[]byte(`{"Name":"Wednesday","Age":6,"Parents":["Gomez","Morticia"]}`), &f)
m := f.(map[string]interface{})
for k, v := range m {
switch vv := v.(type) {
case string:
fmt.Println(k, "is string", vv)
case int:
fmt.Println(k, "is int", vv)
case []interface{}:
fmt.Println(k, "is an array:")
for i, u := range vv {
fmt.Println(i, u)
}
default:
fmt.Println(k, "is of a type I don't know how to handle")
fmt.Println(" Type Is:", vv)
}
}
That is, I declare a variable with an empty interface type. Per the docs, I
use a type assertion to access f's underlying map[string]interface{}:
Then, I use range
to do a for loop over the map's key/value pairs. If the value is a string, int, or []interface, the program says so. If that value is another type, (the default case), the program says I don't know how to handle it. This is almost verbatim code from the manual.
The program produces the following output.
Name is string Wednesday
Age is of a type I don't know how to handle
Type Is: 6
Parents is an array:
0 Gomez
1 Morticia
That is -- it correctly identifies the types of strings and arrays -- for for some reason it seems like the type of the parsed 6
isn't and int
-- it's 6.
So -- I guess my question is either *why does v.(type)
return the actual number oinstead of int
here or my question is why is that the wrong question?
JSON numbers are double precision floats, so the default type go uses is float64
. You can see the defaults listed in the json.Unmarshal
documentation.