I want to parse a JSON file to a map[string]interface{}
:
var migrations map[string]interface{}
json.Unmarshal(raw, &migrations)
fmt.Println(migrations["create_user"])
But I modified my code to point data to interface{}
:
var migrations interface{}
json.Unmarshal(raw, &migrations)
// compile wrong here
fmt.Println(migrations["create_user"])
I don't understand much about difference between map[string]interface{}
and interface{}
in above case.
It is because by default you need to type assert interface{} to get the underlying value of map[string]interface{}.
As per GoLang Specification
For an expression x of interface type and a type T, the primary expression
x.(T)
asserts that x is not nil and that the value stored in x is of type T. The notation x.(T) is called a type assertion.
Also Unmarshal
function requires pointer to migration
of type interface{} or map[string]interface{}
var migrations interface{}
json.Unmarshal(raw, &migrations)
fmt.Println(migrations.(interface{}).(map[string]interface{})["create_user"])
Since migrations
is not a map. So you cannot use its key to get the value. Interface{} don't have keys
The difference between those two types is just what it seems:
interface{}
is the "any" type, since all types implement the interface with no functions.
map[string]interface{}
is a map whose keys are strings and values are any type.
When unmarshaling a byte array from JSON into memory it's easiest to use the interface{}
type, since it can store any type of JSON document (objects, arrays, primitives, etc.); however, it may require more reflection to handle the underlying data. Using a map[string]interface{}
is common when you know the JSON document is an object and []interface{}
is common when you know the document is an array.
However, the best approach for unmarshaling JSON - especially when you know the structure of the documents ahead of time - is to define and use custom struct types that describe the data exactly. This way you can avoid any reflection and improve the legibility of your code.