Search code examples
gointerfacego-map

Difference between map[string]interface{} and interface{}


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.


Solution

  • 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