In this tutorial, we are going to look at maps in Golang, how to create them, add entries to a map, iterate map and delete from a map.
A map is a collection of elements which are grouped in key-value pairs. Each key refers to a single value.
Maps provide faster access and iteration and that is why they commonly used to store data. A map may be visualized as below.
Keys of a map should be of same data type and values of a map should be of same data type. Keys and values may be of different data types.
Data type of keys should be such that they can be compared using
==
or !=
operators.Thus, integers, decimal numbers, strings, pointers, interfaces, arrays and structs can be used as keys while functions, map or slices cannot be used as keys.
Create map
There are two ways to create a map.
1. Using map literal
A map can be created using below syntax
<variable name> := map
[key type]value type {
key1: value1,
key2: value2,
}
where,
variable name is the name of variable with which the map will be accessed.
map
is the Golang literal to create a map. It is followed by square brackets containing the type of keys this map will contain and type of values outside the square brackets.
Map entries or Key–Value pairs are given inside curly braces.
Each Key and Value are separated by a colon while Key–Value pairs are separated by a comma.
Remember that the last Key–Value pair should also end with a comma else there will be a compiler error.
Creating empty map
Below syntax creates an empty map with map literal syntax. Keys of this map are of type int
while values are string
.
m := map[int]string{}
If you do not write curly braces after the declaration, you will get an error
type map[int]string is not an expression
Builtin
make()
function can also be used to create a map. It takes the map
literal as argument.Syntax is
m := make(map[int]string)
This creates an empty map whose keys are of type int
and values are of type string
.
There is another version of make()
which also takes the initial size of map as the second argument.
m := make(map[int]string, 10)
This does not mean that this map can contain only 10 entries. Map can expand its size dynamically when more entries are added.
Remember that when a map is created with make()
, it does not any initial key-value pairs but with map
literal, you can provide default key-value pairs and also add entries later.
Append to map
For adding key-value pairs to a map, below syntax is used
m[key] = value
Data types of key and value should be same as that given while creating a map.
Remember that you can only add entries to an initialized map. If a map is simply declared using var
keyword, then it is nil
and you cannot add values to a nil map.
Thus below code will raise an error.
var m map[string]string m["1"]="A"
as below
panic: assignment to entry in nil map
To resolve this, first check before adding an entry
var m map[string]string if m != nil { m["1"]="A" } else { fmt.Println("Map is not initialized") }
Map example
Following code initializes a map using map
literal and then adds an entry into it.
package main import "fmt" func main() { // create a map m := map[int]string { 1:"A", 2:"B", } // add entry to map m[3]="C" fmt.Println("Map is", m) }
When the map is printed, it gives
Map is map[1:A 2:B 3:C]
Notice that it contains all the key-value pairs.
Below code example creates a map with make()
function and then adds all the three entries.
package main import "fmt" func main() { // create a map m := make(map[int]string) m[1]="A" m[2]="B" m[3]="C" fmt.Println("Map is", m) }
Access values
In order to get a value associated with a key, use map variable followed by the name of key enclosed in square brackets.
Syntax is
map-variable[key-name]
This returns the value linked to the given key.
If the key is not present in the map, then it returns the zero value for the corresponding data type of the value.
Example
package main import "fmt" func main() { // create a map m := make(map[int]int) // assign key-values m[1] = 10 m[2] = 20 m[3] = 30 fmt.Println("Value for key 1 is", m[1]) fmt.Println("Value for key 2 is", m[2]) fmt.Println("Value for key 3 is", m[3]) // access non-existing key fmt.Println("Value for key 4 is", m[4]) }
This prints
Value for key 1 is 10
Value for key 2 is 20
Value for key 3 is 30
Value for key 4 is 0
Look, for a key that does not exist, it prints 0, which is the zero value for int
data type.
Iterating a map means looping over its entries. A map can be iterated using a for loop with
range
clause.Syntax is
for key, value := range map { }
where key and value are variable names that contain the key and value of a map in every iteration. Example,
package main import "fmt" func main() { // create a map m := make(map[int]int) m[1] = 10 m[2] = 20 m[3] = 30 for k, v := range m { fmt.Println("Key is:",k, ", Value is:",v) } }
This prints
Key is: 1 , Value is: 10
Key is: 2 , Value is: 20
Key is: 3 , Value is: 30
If you need only the key, then drop the second variable from for
loop as below
// only key is required for k:= range m { fmt.Println("Key is:",k) }
If you need only the value, then replace the key
variable with a blank identifier otherwise, you will have to use this variable to prevent a compiler error.
// key not required for _, v := range m { fmt.Println("Value is:",v) }
Delete Entry
For removing a key-value pair from map, use delete()
function passing it the map variable and the key of the entry to be deleted as
delete(m, key)
Example,
package main import "fmt" func main() { // create a map m := make(map[int]int) m[1] = 10 m[2] = 20 m[3] = 30 fmt.Println("Original map:",m) delete(m,2) fmt.Println("Map after deletion:",m) }
which prints
Original map: map[1:10 2:20 3:30] Map after deletion: map[1:10 3:30]
If a non-existing key is provided as argument to delete()
, nothing happens. Thus,
// no effect delete(m, 5)
Since Golang does not give any error on missing key and it returns a value(the zero value) even if a key is not present, you need to have some way of checking for key presence.
You can test if a key is present in the map or not using the same syntax as for accessing a key
map[key]
Assign this to two comma separated variables, out of which first one contains the value and second is a bool
which is true
if the key is present and false
if it is not as shown in the following example
// create a map m := map[string]string{ "ram":"2GB", "hdd":"350GB", } // declare variables var value string var ok bool // access key value, ok = m["camera"]
In this case, ok
will be false
and value will be empty string.
You can check for key presence and then take a relevant action using if-else blocks as below
if ok { fmt.Println("Value is",value) } else { fmt.Println("Key not present") }
In Golang, this is called comma ok idiom.
It is not necessary to name the bool
variable as ok
, it can be any user defined name.
Variable declarations in this example can be shortened by using :=
operator as
// create a map m := map[string]string{ "ram":"2GB", "hdd":"350GB", } // access key value, ok := m["camera"]
Hope the article was useful.