Introduction to Maps in Golang

A map in Go language is a built-in data structure that is used to store the key-value pairs. It is mostly used for fast lookups or retrieval of the data using a key inside the map.

  • A key in the map can be of any type (as long as values of that type can be compared using ==) whereas other data structures like arrays and slices can only use integers as the indexes
  • The values have to be of the same type, and the keys also have to be of the same type, but the types of keys and values could be different
  • We cannot have duplicate keys within a map in the Go language

In this post, we are going to look at the below points.

Let’s have a look at all of these points one by one.

How to create a map in the Go language

To declare a variable that will hold a map, we will just have to type the map keyword, followed by the square brackets ( [ ] ) containing the type of the key, and then following the brackets, we will have to provide the type of the value that our map will hold.

Declaration of map in Go language

This declaration of the map doesn’t automatically create it. We still have to call the make() function to create it by passing the type of the map into the make() function argument.

var theMap map[string]int   // only declared the map
theMap = make(map[string]int)   // actually created it

package main

import (
	"fmt"
)

func main() {

	var theMap map[string]int     // declaring the map
	theMap = make(map[string]int) // actually creating it

	fmt.Println(theMap)

}

Output –

map[]

It’s printing an empty map because we have only created a map and haven’t added any key-value pairs yet. In the above program, we can also use the shorthand declaration to create the map in a single line only.

theMap := make(map[string]int) // creating a map using shorthand declaration

Adding key-value pairs to a map

Below is the syntax for adding a key-value pair into a map.

mapName[key] = value

Code example

package main

import (
	"fmt"
)

func main() {

	theMap := make(map[string]int)

	theMap["hello"] = 10
	theMap["codekru"] = 20

	fmt.Println("value of codekru within the map is:", theMap["codekru"])

}

Output –

value of codekru within the map is: 20

Here, we have added only two key-value pairs to the map.

Map literals

Just like the array literals or slice literals, we also have the map literals. So, if you know the keys and their values in advance, then you can use a map literal to create a map without using the make() function.

  • A map literal starts with a map type in the form of map[TypeOfKey][TypeOfValue]
  • Then key/value pairs will be enclosed within the curly braces
  • For each pair, the key and the value will be separated by a colon ( : )
  • And multiple key-value pairs will be separated by the comma ( , )

Syntax

theMap := map[TypeOfKey]TypeOfValue{key1:value1 , key2:value2,....}

Code example

package main

import (
	"fmt"
)


func main() {

	theMap := map[string]int{"hello": 10, "codekru": 20}

	fmt.Println("The value of the codekru in theMap is:", theMap["codekru"])

}

Output –

The value of the codekru in theMap is: 20

Zero values for a Map in Golang

The zero values of the key or the value will depend upon their types. Eg. – For int, it will be 0 and for string, it will be an empty string. But the zero value for a map is nil. And, if we try to add a key-value pair into such a map, then it will cause a panic as illustrated in the below program.

package main

import (
	"fmt"
)

func main() {

	var theMap map[string]int

	theMap["hello"] = 10
	theMap["codekru"] = 20

	fmt.Println("The value of the codekru in theMap is:", theMap["codekru"])

}

Output –

panic: assignment to entry in nil map

goroutine 1 [running]:
main.main()
        D:/codekru.go:11 +0x56
exit status 2

So, we always have to initialize a map to avoid this kind of situation. And if we have created a map but haven’t put any key-value pairs, then the zero values for the corresponding type will be assigned to them.

package main

import (
	"fmt"
)

func main() {

	theMap := make(map[string]int)

	fmt.Println("value of codekru within the map is:", theMap["codekru"])

}

Output –

value of codekru within the map is: 0

Here, we can see that zero ( 0 ) is printed in the output though we haven’t put any key into the map yet. This is because zero ( 0 ) is the zero value for an int data type. But what if we put a key with a value equal to the value’s type zero value, as shown in the below program.

package main

import (
	"fmt"
)

func main() {

	theMap := make(map[string]int)

	theMap["codekru"] = 0

	fmt.Println("value of codekru within the map is:", theMap["codekru"])

}

Output –

value of codekru within the map is: 0

Here, we have explicitly entered a key “codekru” with the value 0. If we look closer at the above two programs now, then we can observe that the result is the same, no matter whether the key has been assigned a value or not. Then, how we will be able to detect whether a key is present in the map or not?

How to tell the zero values apart from the assigned values( Check If key exits)

Zero values can sometimes make it more difficult to tell whether a given key has been assigned the zero value, or the value has never been assigned as we saw in the above program.

Solution – While accessing a key, we also get a second optional boolean value along with the actual value which tells us whether that particular key has been put inside the map or not. That boolean value will be true if a value has been assigned to that key, otherwise, it will be false.

package main

import (
	"fmt"
)

func main() {

	theMap := make(map[string]int)

	value, isValueAssigned := theMap["codekru"]

	fmt.Println("Before assigning values::::::")
	fmt.Println("Is value was assigned to key named codekru?:", isValueAssigned)
	fmt.Println("Actual value returned:", value)

	// assigning the value
	theMap["codekru"] = 20

	value, isValueAssigned = theMap["codekru"]

	fmt.Println("After assigning values::::::")
	fmt.Println("Is value was assigned to key named codekru?:", isValueAssigned)
	fmt.Println("Actual value returned:", value)

}

Output –

Before assigning values::::::
Is value was assigned to key named codekru?: false
Actual value returned: 0
After assigning values::::::
Is value was assigned to key named codekru?: true
Actual value returned: 20

Here, we can see that if we try to access a key before inserting it into the map, then isValueAssigned returned false whereas it returned true after inserting the corresponding key-value pair. In this way, we can check whether a map is returning a zero value or a value explicitly assigned to that key.

If we only want to check whether a key is present within a map or not, then we can omit the actual value by using the blank identifier ( _ ) as illustrated in the below program.

package main

import (
	"fmt"
)

func main() {

	theMap := make(map[string]int)

	_, ok := theMap["codekru"]

	fmt.Println("Does codekru key exist within the map?", ok)

}

Output –

Does codekru key exist within the map? false

We can easily print the whole map at once as shown in the program below.

package main

import (
	"fmt"
)

func main() {

	theMap := make(map[string]int)

	theMap["hello"] = 10
	theMap["codekru"] = 20

	fmt.Println("Map contents:", theMap) // printing the whole map

}

Output –

Map contents: map[codekru:20 hello:10]

Related Articles

Hope you have liked the article. If you have any doubts or concerns, please feel free to write us in the comments or mail us at [email protected]

Liked the article? Share this on

Leave a Comment

Your email address will not be published.