Go Maps
A map stores data by connecting keys to values, and every element is one key:value pair.
Elements have no fixed order, you can change them freely, and the same key cannot appear twice.
To find how many elements a map has, which is its length, call len().
A map that has not been initialized has the value nil.
Under the hood, a map holds references to a hash table.
Go gives you several ways to create a map, and the next sections go through them.
Create Maps Using var and :=
The var keyword and the short declaration operator := both work for creating a map with starting values.
Note: Don't expect a map to keep the order you wrote in your code. Go arranges the stored data its own way so that looking values up stays fast.
Example
Output: Go program and captured output
package main
import ("fmt")
func main() {
var a = map[string]string{"brand": "Ford", "model": "Mustang", "year": "1964"}
b := map[string]int{"Oslo": 1, "Bergen": 2, "Trondheim": 3, "Stavanger": 4}
fmt.Printf("a\t%v\n", a)
fmt.Printf("b\t%v\n", b)
}
Syntax: Map With var and :=
var a = map[KeyType]ValueType{key1:value1, key2:value2,...}
b := map[KeyType]ValueType{key1:value1, key2:value2,...}
Create Maps Using the make() Function
The make() function is another option. It gives you a map that you can then fill one key at a time.
Example
Output: Go program and captured output
package main
import ("fmt")
func main() {
var a = make(map[string]string)
a["brand"] = "Ford"
a["model"] = "Mustang"
a["year"] = "1964"
b := make(map[string]int)
b["Oslo"] = 1
b["Bergen"] = 2
b["Trondheim"] = 3
b["Stavanger"] = 4
fmt.Printf("a\t%v\n", a)
fmt.Printf("b\t%v\n", b)
}
Syntax: Map With make()
var a = make(map[KeyType]ValueType)
b := make(map[KeyType]ValueType)
Create an Empty Map
An empty map can come from the make() function, or from a var declaration with no initial value.
Note: Only the first of these is ready to use, so make() is the one to choose. The var version is nil, as the output shows, and writing to it causes a runtime panic.
Example
Output: Go program and captured output
package main
import ("fmt")
func main() {
var a = make(map[string]string)
var b map[string]string
fmt.Println(a == nil)
fmt.Println(b == nil)
}
Allowed Key Types
A key can use any type that supports the equality operator (==), because Go must be able to compare keys. That covers:
- Booleans
- Numbers
- Strings
- Arrays
- Pointers
- Structs
- Interfaces (provided the dynamic type can be compared for equality)
Three types cannot be keys:
- Slices
- Maps
- Functions
The reason is that == is not defined for any of them.
Allowed Value Types
Values have no such limit: a map can hold values of any type.
Access Map Elements
To read an element, put its key in square brackets after the map's name.
Example
Output: Go program and captured output
package main
import ("fmt")
func main() {
var a = make(map[string]string)
a["brand"] = "Ford"
a["model"] = "Mustang"
a["year"] = "1964"
fmt.Printf(a["brand"])
}
Syntax: Access a Map Element
value = map_name[key]
Update and Add Map Elements
Assigning a value to a key does two jobs. If the key already exists, its value is updated; if not, a new element is added.
Example
Output: Go program and captured output
package main
import ("fmt")
func main() {
var a = make(map[string]string)
a["brand"] = "Ford"
a["model"] = "Mustang"
a["year"] = "1964"
fmt.Println(a)
a["year"] = "1970"
a["color"] = "red"
fmt.Println(a)
}
Syntax: Update a Map Element
map_name[key] = value
Remove Element from Map
Call the delete() function with the map and a key to remove that element.
Example
Output: Go program and captured output
package main
import ("fmt")
func main() {
var a = make(map[string]string)
a["brand"] = "Ford"
a["model"] = "Mustang"
a["year"] = "1964"
fmt.Println(a)
delete(a, "year")
fmt.Println(a)
}
Syntax: Delete a Map Element
delete(map_name, key)
Check For Specific Elements in a Map
Looking up a key can return two values, which gives the val, ok pattern. ok tells you whether the key exists, even when its value is empty, as with day in the example.
When the existence of the key is all you care about, put the blank identifier (_) where val would go.
Example
Output: Go program and captured output
package main
import ("fmt")
func main() {
var a = map[string]string{"brand": "Ford", "model": "Mustang", "year": "1964", "day": ""}
val1, ok1 := a["brand"]
val2, ok2 := a["color"]
val3, ok3 := a["day"]
_, ok4 := a["model"]
fmt.Println(val1, ok1)
fmt.Println(val2, ok2)
fmt.Println(val3, ok3)
fmt.Println(ok4)
}
Syntax: Check a Map Key
val, ok := map_name[key]
Maps Are References
A map variable refers to a hash table rather than containing the data itself.
So when two variables point at one hash table, a change made through either variable is visible through the other.
Example
Output: Go program and captured output
package main
import ("fmt")
func main() {
var a = map[string]string{"brand": "Ford", "model": "Mustang", "year": "1964"}
b := a
fmt.Println(a)
fmt.Println(b)
b["year"] = "1970"
fmt.Println("After change to b:")
fmt.Println(a)
fmt.Println(b)
}
Iterate Over Maps
A range loop walks through every key and value in a map. Don't count on the order, since it can change from one run to the next.
Example
Output: Go program and captured output
package main
import ("fmt")
func main() {
a := map[string]int{"one": 1, "two": 2, "three": 3, "four": 4}
for k, v := range a {
fmt.Printf("%v : %v, ", k, v)
}
}
Iterate Over Maps in a Specific Order
A map has no order of its own. To visit its elements in a particular sequence, keep that sequence in another data structure, such as a slice of keys, and loop over that instead.
Example
Output: Go program and captured output
package main
import ("fmt")
func main() {
a := map[string]int{"one": 1, "two": 2, "three": 3, "four": 4}
var b []string
b = append(b, "one", "two", "three", "four")
for k, v := range a {
fmt.Printf("%v : %v, ", k, v)
}
fmt.Println()
for _, element := range b {
fmt.Printf("%v : %v, ", element, a[element])
}
}