Using the switch case you can fetch the value underlying the interface. The function will run recursively until it gets the original type of the parsed json.
func fetchValue(value interface{}) { // pass the interface value from the struct in this function as it will run recursively to get the value.
switch value.(type) {
case string:
fmt.Printf("%v is an string \n ", value.(string))
case bool:
fmt.Printf("%v is bool \n ", value.(bool))
case float64:
fmt.Printf("%v is float64 \n ", value.(float64))
case []interface{}:
fmt.Printf("%v is a slice of interface \n ", value)
for _, v := range value.([]interface{}) {
fetchValue(v)
}
case map[string]interface{}:
fmt.Printf("%v is a map \n ", value)
for _, v := range value.(map[string]interface{}) {
fetchValue(v)
}
default:
fmt.Printf("%v is unknown \n ", value)
}
}
The reason behind the types in switch to be limited is defined in the golang spec for unmarshal where it is clearly described what values the json will parse into when unmarshaling using interface{}:
To unmarshal JSON into an interface value, Unmarshal stores one of
these in the interface value:
bool, for JSON booleans
float64, for JSON numbers
string, for JSON strings
[]interface{}, for JSON arrays
map[string]interface{}, for JSON objects
nil for JSON null