Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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.

like image 428
Trần Kim Dự Avatar asked Feb 26 '18 12:02

Trần Kim Dự


People also ask

What is interface {} Golang?

interface{} means you can put value of any type, including your own custom type. All types in Go satisfy an empty interface ( interface{} is an empty interface). In your example, Msg field can have value of any type.

What is map string string in Golang?

Golang Maps is a collection of unordered pairs of key-value. It is widely used because it provides fast lookups and values that can retrieve, update or delete with the help of keys. It is a reference to a hash table.

What is map interface in Java?

The map interface is present in java. util package represents a mapping between a key and a value. The Map interface is not a subtype of the Collection interface. Therefore it behaves a bit differently from the rest of the collection types. A map contains unique keys.

Is map a type in Golang?

What is actually a map in Golang?. There's no such specific data type in Golang called map; instead, we use the map keyword to create a map with keys of a certain type and values of another type (or the same type).


2 Answers

The difference between those two types is just what it seems:

  1. interface{} is the "any" type, since all types implement the interface with no functions.

  2. 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.

like image 54
maerics Avatar answered Oct 05 '22 06:10

maerics


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

like image 44
Himanshu Avatar answered Oct 05 '22 06:10

Himanshu