Chapter 7 of 20
Maps
Declaration, CRUD, iteration, concurrency safety
Declaration and Initialization
package main
import "fmt"
func main() {
m := map[string]int{
"alice": 30,
"bob": 25,
}
// using make
m2 := make(map[string]int)
m2["x"] = 1
fmt.Println(m, m2)
}Read / Write / Delete
package main
import "fmt"
func main() {
m := map[string]int{"alice": 30, "bob": 25}
m["alice"] = 31 // write
v := m["alice"] // read
fmt.Println(v)
if cv, ok := m["carol"]; ok { // check for existence
fmt.Println("carol:", cv)
} else {
fmt.Println("carol missing")
}
delete(m, "bob") // delete
fmt.Println(m)
}Iteration
range iterates a map in random order; if you need a specific order, sort the keys first.
package main
import (
"fmt"
"sort"
)
func main() {
m := map[string]int{"bob": 1, "alice": 2, "carol": 3}
keys := make([]string, 0, len(m))
for k := range m {
keys = append(keys, k)
}
sort.Strings(keys)
for _, k := range keys {
fmt.Println(k, m[k])
}
}Concurrency Safety
Maps are not concurrency-safe. Concurrent read/write across goroutines needs a lock, or use sync.Map (suited to read-heavy workloads with a relatively stable key set).
package main
import (
"fmt"
"sync"
)
func main() {
var (
mu sync.Mutex
m = map[string]int{}
)
set := func(k string, v int) {
mu.Lock()
defer mu.Unlock()
m[k] = v
}
var wg sync.WaitGroup
for i := 0; i < 10; i++ {
wg.Add(1)
go func(i int) {
defer wg.Done()
set(fmt.Sprintf("k%d", i), i)
}(i)
}
wg.Wait()
fmt.Println(len(m))
}