Работа с map в Go имеет несколько важных синтаксических особенностей, которые отличают их от других коллекций. Рассмотрим детально операции чтения и записи.
value := m[key]
Особенности:
value, ok := m[key]
if ok {
// ключ существует
}
Особенности:
m[key] = value
Особенности:
var m map[string]int
m = make(map[string]int) // обязательно инициализировать!
m["key"] = 42 // паника без make
Важно: Неинициализированная map равна nil, и попытка записи вызовет панику
m := make(map[int]int)
go func() {
for {
m[1] = 1 // запись
}
}()
go func() {
for {
_ = m[1] // чтение
}
}()
// Будет паника: concurrent map read and map write
Решение: Использовать sync.Mutex или sync.Map
delete(m, key)
Особенности:
for key, value := range m {
fmt.Println(key, value)
}
Особенности:
Нельзя использовать:
m1 := make(map[[2]int]string) // массив - можно
m2 := make(map[struct{x int}]string) // структура с comparable полями - можно
if _, ok := m[key]; !ok {
m[key] = defaultValue
}
m[key]++ // эквивалентно m[key] = m[key] + 1
length := len(m)
Особенность: len возвращает количество элементов, а не емкость
m1 := map[int]int{1: 1}
m2 := map[int]int{1: 1}
// fmt.Println(m1 == m2) // ошибка: map can only be compared to nil
Особенность: Map можно сравнивать только с nil
m := map[string]int{
"Alice": 25,
"Bob": 30,
}
Особенности: