Maps in Go: A Practical Guide with Examples
A Go map stores key-value pairs and gives you fast lookup by key. It is similar to a dictionary or hash map in other languages and is one of Go’s most useful built-in data structures.
Creating a Map
Using make:
personAge := make(map[string]int)
personAge["Alice"] = 30
personAge["Bob"] = 25
fmt.Println(personAge)Using a map literal:
personAge := map[string]int{"Alice": 30, "Bob": 25}
fmt.Println(personAge)Accessing and Updating Values
fmt.Println(personAge["Alice"]) // 30
personAge["Alice"] = 31
delete(personAge, "Bob")Reading a missing key returns the zero value for the map’s value type. If you need to distinguish a missing key from a stored zero value, use the two-result lookup form.
Checking Whether a Key Exists
age, exists := personAge["Bob"]
if exists {
fmt.Println(age)
} else {
fmt.Println("Bob not found")
}If you only care whether the key exists, discard the value:
_, exists := personAge["Bob"]Iterating over a Map
for name, age := range personAge {
fmt.Printf("%s is %d years old\n", name, age)
}Map iteration order is deliberately unspecified. Sort the keys first if output order matters.
Passing a Map to a Function
Assignments to map entries performed inside a function are visible to the caller:
func updateAge(m map[string]int, name string, newAge int) {
m[name] = newAge
}
updateAge(personAge, "Alice", 32)
fmt.Println(personAge["Alice"]) // 32Maps with Struct Values
Maps can store any valid value type, including structs:
type Person struct {
Age int
Address string
}
people := map[string]Person{
"Alice": {Age: 30, Address: "123 Main St"},
"Bob": {Age: 25, Address: "456 Elm St"},
}
fmt.Println(people["Alice"])Important Map Rules
- A nil map can be read safely, but writing to it causes a panic. Initialize writable maps with
makeor a literal. - Map keys must be comparable. Strings, numbers, pointers, arrays, and structs containing comparable fields can be keys; slices, maps, and functions cannot.
- Maps are not safe for unsynchronized concurrent writes. Use synchronization or a design that avoids shared mutation when multiple goroutines access the same map.
Conclusion
Maps are ideal when data should be retrieved by a meaningful key. Once you are comfortable with lookup, insertion, deletion, iteration, and the value, ok idiom, they become a simple and efficient tool for many Go programs.