Maps
Overview
Maps are Go’s built-in hash table type, providing O(1) average-time lookups, insertions, and deletions.
Creating Maps
var m map[string]int // nil map (read-only!)
m := make(map[string]int) // Empty, ready to use
m := make(map[string]int, 100) // With capacity hint
m := map[string]int{ // Literal
"one": 1,
"two": 2,
}Basic Operations
Set
m["key"] = valueGet
val := m["key"] // Returns zero value if missingDelete
delete(m, "key") // No-op if key doesn't existCheck Existence
val, ok := m["key"]
if ok {
// Key exists
}
if _, exists := m["key"]; exists {
// Key exists
}nil Map Behavior
var m map[string]int // nil
val := m["key"] // OK: returns 0
m["key"] = 1 // PANIC! Cannot write to nil mapAlways initialize before writing:
m := make(map[string]int)
m["key"] = 1 // OKIteration
for key, value := range m {
fmt.Printf("%s: %d\n", key, value)
}
for key := range m { // Keys only
fmt.Println(key)
}Warning: Iteration order is randomized!
Common Patterns
Set (Unique Values)
set := make(map[string]struct{})
set["item"] = struct{}{}
if _, exists := set["item"]; exists {
// Item is in set
}
delete(set, "item")Counter
counter := make(map[string]int)
for _, word := range words {
counter[word]++ // Zero value works!
}Grouping
groups := make(map[string][]User)
for _, user := range users {
groups[user.Country] = append(groups[user.Country], user)
}Default Value
val := m["key"]
if val == 0 {
val = defaultValue
}Concurrency Warning
Maps are not goroutine-safe:
// Unsafe: concurrent read/write
go func() { m["key"] = 1 }()
go func() { _ = m["key"] }()
// Use sync.Map or mutex
var mu sync.Mutex
mu.Lock()
m["key"] = 1
mu.Unlock()The maps Package (Go 1.21+)
The standard library maps package provides generic utilities for common operations.
import "maps"
maps.Clone(m) // Shallow copy
maps.Equal(m1, m2) // Compare
maps.DeleteFunc(m, func(k K, v V) bool {
return v < 10 // Conditional delete
})Modern Loop Pattern (Go 1.23+)
Using iterators with maps:
for k, v := range maps.All(m) { /* ... */ }
for k := range maps.Keys(m) { /* ... */ }
for v := range maps.Values(m) { /* ... */ }Map Internals
- Keys must be comparable (
==must work) - Valid key types: bool, numeric, string, pointer, channel, interface, structs/arrays of comparable types
- Invalid: slices, maps, functions
Summary
| Operation | Syntax |
|---|---|
| Create | make(map[K]V) |
| Set | m[key] = value |
| Get | val := m[key] |
| Check | val, ok := m[key] |
| Delete | delete(m, key) |
| Length | len(m) |