Мапы¶
TL;DR¶
map[K]V— hashmap, доступ O(1) amortized.v, ok := m[k]— comma-ok idiom для проверки.- Итерация в случайном порядке.
- nil map можно читать (вернёт zero value), писать в неё — panic.
- Запись из нескольких горутин одновременно — fatal error.
Создание¶
m := map[string]int{"a": 1, "b": 2}
m := make(map[string]int)
m := make(map[string]int, 100) // подсказка по capacity
var m map[string]int // nil map, читать можно, писать нельзя
Comma-ok¶
Без ok нельзя отличить «нет ключа» от «значение == zero».
Конкурентность¶
Map в Go не thread-safe. Несколько горутин одновременно пишут → fatal error: concurrent map writes.
Варианты:
// 1. Mutex
var m = struct{
sync.RWMutex
data map[string]int
}{data: map[string]int{}}
m.Lock()
m.data["a"] = 1
m.Unlock()
// 2. sync.Map — но только если ключи редко меняются и читателей сильно больше
var sm sync.Map
sm.Store("a", 1)
v, ok := sm.Load("a")
Когда sync.Map лучше: read-mostly, write-rare. В общем случае
map + Mutex быстрее.
Гочча — нельзя взять адрес¶
Map может быть переаллоцирован при росте → адреса нестабильны.
Гочча — итерация в случайном порядке¶
Это сделано намеренно, чтобы код не полагался на порядок. Если порядок нужен — собери ключи в slice, отсортируй, итерируй по slice.
📖 Связанные задачи: must-solve-100 → C-005, C-011.