Golang Maps Explained in layman's terms with Examples


GO

Reviewer: Deepak Prasad

Maps are very important data structures in Go and many other programming languages. In other languages it is called a dictionary for python, associative array in Php , hash tables in Java and Hash maps in JavaScript. In all these languages maps share some implementation  such as capability to delete , add and lookup of data.

 

Getting started with Golang Maps

Go maps have the following characteristics that makes them different from structs and interfaces.

  • Maps are made up of mainly two parts, key and value. So it's a key value data type.
  • The key and value pair are not ordered , and they are changeable
  • Maps does not allow duplicates of key and value
  • Maps sits on top of a hash table, therefore they always reference hash tables beneath them
  • The zero value of a map is a nil. A nil map is the same as an empty map except that elements can not be added.
  • Maps use the len() function to get the size of a map.

 

How to declare maps in golang

Maps are created with the built-in make function, just as for slices. The type for a map is specified using the map keyword, followed by the key type in square brackets, followed by the value type. The final argument to the make function specifies the initial capacity of the map. Maps, like slices, are resized automatically, and the size argument can be omitted.

Golang Maps Explained in layman's terms with Examples

 

A typical Go map type looks like below.

map[KeyType]ValueType
  • KeyType : This is any type that is comparable
  • ValueType : This is any type in Go, e.g struct, map, string, int

 

Declaring maps using the var keyword

To declare a variable that holds a map, you type the map keyword, followed by square brackets ([]) containing the key type. Then, following the brackets, provide the value type. Just as with slices, declaring a map variable doesn’t automatically create a map; you need to call the make function (the same function you can use to create slices). Instead of a slice type, you can pass make the type of the map you want to create (which should be the same as the type of the variable you’re going to assign it to).

Golang Maps Explained in layman's terms with Examples

Therefore the value of employees is nil because it does not point to an initialized map. Since a nil map behaves like an empty map, attempts to write to it (nil map) will result in a panic.

Example

package main
 
import (
   "fmt"
   "reflect"
)
 
func main() {
   var employees map[string]int
   fmt.Println(employees)
   fmt.Println(reflect.TypeOf(employees))
 
   if employees == nil {
       fmt.Println("Employee map is nil")
   } else {
       fmt.Println("Employee map is not nil")
   }
 
   employees["John Doe"] = 1
 
   fmt.Println(employees)
}

Output

go run main.go
map[]
map[string]int
Employee map is nil
panic: assignment to entry in nil map
 
goroutine 1 [running]:
main.main()
       /GoLinuxCloud/user/Go/maps/main.go:19 +0x111
exit status 2

Explanation

In the above example, inside the main function we declare an employee map of string keys to int values. Printing out the contents of the employee map, results in an empty map i.e map[]in the output. The next line prints out the type of employee data type using the reflectpackage. This results in map[string]intin the output. Using the if statement we check if a map is nil or not. The next line is important because we are trying to assign a new key to the map, which is not possible. The map is empty (nil map), and attempts to write to it results in a panic as shown in the output.

 

Initializing map using map literal

Just as with arrays and slices, if you know keys and values that you want your map to have in advance, you can use a map literal to create it. A map literal starts with the map type (in the form map[KeyType]ValueType). This is followed by curly braces containing key/value pairs you want the map to start with. For each key/value pair, you include the key, a colon, and then the value. Multiple key/value pairs are separated by commas.

Golang Maps Explained in layman's terms with Examples

It's easy to declare and initialize a map at the same time using := operator. Create the key value pair separated by a colon and ensure that the last key value pair has a comma at the end as shown below.

Example

package main
 
import (
   "fmt"
)
 
func main() {
   employees := map[string]int{
       "John Doe": 23,
       "Mary Doe": 19,
   }
   fmt.Println(employees)
 
   if employees == nil {
       fmt.Println("Employee map is nil")
   } else {
       fmt.Println("Employee map is not nil")
   }
}

Output

go run main.go
map[John Doe:23 Mary Doe:19]
Employee map is not nil

 

Initializing a map using the make() function

It is possible to initialize a Go map using the built in make() function. The make function allocates and initializes a hash map data structure at the same time. The make() function returns a map value that points to it. The make function is passed to the map type and an optional initial capacity of the map.

Example

package main
 
import (
   "fmt"
)
 
func main() {
   employees := make(map[string]int, 5)
 
   fmt.Println(employees)
 
   if employees == nil {
       fmt.Println("Employee map is nil")
   } else {
       fmt.Println("Employee map is not nil")
   }
   employees["John Doe"] = 23
   employees["Mary Doe"] = 19
 
   fmt.Println(employees)
}

Output

go run main.go
map[]
Employee map is not nil
map[John Doe:23 Mary Doe:19]

Explanation

We create a Go map using the make()function , that takes map data type and the capacity of the map. The output after initializing the map like this is an empty map. We then check if the map is nil or not. Using the above example, our employee map is not nil, meaning the make()function does not return a nil value.To add a new key value pair, use the square brackets to define a new key and value as shown in the above example i.e  employees[“John Doe”] = 23. The map now contains the new key value pair assigned to it.

 

Adding Key value pair in a Go map

To add a key, value pair , we assign a new value with the key as shown in the example below.

Example

package main
 
import (
   "fmt"
)
 
func main() {
   employees := make(map[string]int)
   employees["John Doe"] = 45
   employees["Stephanie Doe"] = 21
   employees["Tom Doe"] = 33
   employees["Mary Doe"] = 12
 
   fmt.Println(employees)
}

Output

go run main.go
map[John Doe:45 Mary Doe:12 Stephanie Doe:21 Tom Doe:33]

 

Accessing values in a Go map

We can get access to a value of a map using the key that exists in the map. Using a key that does not exist in the map returns a zero (0) value. In the below example we try to access an existing key employeeOne := employees["John Doe"] and a not existing key newEmployee := employees["Mike"]

Example

package main
 
import (
   "fmt"
)
 
func main() {
   employees := make(map[string]int)
   employees["John Doe"] = 45
   employees["Stephanie Doe"] = 21
   employees["Tom Doe"] = 33
   employees["Mary Doe"] = 12
 
   employeeOne := employees["John Doe"]
   newEmployee := employees["Mike"]
 
   fmt.Println(employeeOne)
   fmt.Println(newEmployee)
}

Output

go run main.go
45 
0

 

Changing the value of a map in Go

To change a value in a Go map, use an already existing key and assign it the new value. Please note that it's important to use an already existing key, otherwise a new key value pair will be created if you use a key that does not exist in the map.

Example

package main
 
import (
   "fmt"
)
 
func main() {
   employees := make(map[string]int)
   employees["John Doe"] = 45
   employees["Stephanie Doe"] = 21
   employees["John Doe"] = 40
   employees["Stephanie Doe"] = 30
   fmt.Printf("Updated employees map %v \n", employees)
}

Output

go run main.go
Updated employees map map[John Doe:40 Stephanie Doe:30]

 

Deleting element from a Go map

Go maps use the built in delete()function to delete a key value pair from the map. The delete function takes the map you want to delete elements from as the first argument , followed by the second argument, being the key you want to delete.

Example

package main
 
import "fmt"
 
func main() {
   employees := make(map[string]int)
   employees["John Doe"] = 45
   employees["Stephanie Doe"] = 21
 
   delete(employees, "John Doe")
   fmt.Println(employees)
}

Output

go run main.go
map[Stephanie Doe:21]

 

Checking if a key exists in a map

To check if a key exists in a map, use the two value assignment syntax.  The first value return is the existing value and the second value is a boolean type. The boolean type will return true if the key exists, or false otherwise.

Example

package main
 
import (
   "fmt"
)
 
func main() {
   users := map[string]int{
       "John":  21,
       "David": 43,
       "Paul":  54,
   }
 
   value, exist := users["John"]
 
   if exist {
       fmt.Printf("Found %d %v \n", value, exist)
   } else {
       fmt.Printf("Not found %d %v ", value, exist)
   }
}

Output

go run main.go
Found 21 true

 

Using for range loops with Golang maps

Go map is an iterable type and the range keyword can be used to iterate over Go map key value pairs.  While looping over a map using range ,the order of the output will not be the same from one iteration to the next.

Golang Maps Explained in layman's terms with Examples

The for...range loop makes it easy to loop through a map’s keys and values. Just provide a variable to hold each key, and another to hold the corresponding value, and it will automatically loop through each entry in the map.

Example

package main
 
import (
   "fmt"
)
 
func main() {
   users := map[string]int{
       "John":  21,
       "David": 12,
       "Paul":  23,
   }
   for userName, userAge := range users {
       fmt.Printf("%s is %d years old \n", userName, userAge)
   }
}

Output

go run main.go
John is 21 years old
David is 12 years old
Paul is 23 years old

 

Using for range loop through ordered map

The for...range loop processes map keys and values in a random order because a map is an unordered collection of keys and values. When you use a for...range loop with a map, you never know what order you’ll get the map’s contents in!. In scenarios where the order is a must, use a different data structure that specifies  the order like a slice.

Example

package main
 
import (
   "fmt"
   "sort"
)
 
func main() {
   users := map[int]string{
       100: "John",
       23:  "Mary",
       54:  "Paul",
       21:  "Josh",
   }
   var keys []int
 
   for key := range users {
       keys = append(keys, key)
   }
   sort.Ints(keys)
 
   for _, key := range keys {
       fmt.Printf("Key : %d and Value : %s \n", key, users[key])
   }
}

Output

go run main.go
Key : 21 and Value : Josh
Key : 23 and Value : Mary
Key : 54 and Value : Paul
Key : 100 and Value : John

 

Summary

Go maps play an important role when developing applications. They are known to work better when reading , adding, and deleting values. It offers simple searches with the aid of keys and  is one of the useful data structures in computer science.

 

References

https://go.dev/blog/maps

 

Antony Shikubu

Antony Shikubu

He is highly skilled software developer with expertise in Python, Golang, and AWS cloud services. Skilled in building scalable solutions, he specializes in Django, Flask, Pandas, and NumPy for web apps and data processing, ensuring robust and maintainable code for diverse projects. You can reach out to him on his LinkedIn profile.

Can't find what you're searching for? Let us assist you.

Enter your query below, and we'll provide instant results tailored to your needs.

If my articles on GoLinuxCloud has helped you, kindly consider buying me a coffee as a token of appreciation.

Buy GoLinuxCloud a Coffee

For any other feedbacks or questions you can send mail to admin@golinuxcloud.com

Thank You for your support!!

Leave a Comment