Словари (map)
map — словарь Go: создание, доступ, удаление и важная идиома проверки ok.
map — хеш-таблица: коллекция пар «ключ — значение» с быстрым доступом по ключу. Аналог dict в Python и объекта-словаря в JavaScript.
Создание и заполнение
Тип записывается как map[КлючТип]ЗначениеТип. Создают map литералом или через make. Внимание: nil-map (объявленная через var без инициализации) доступна на чтение, но запись в неё вызовет панику — поэтому используйте make или литерал.
package main
import "fmt"
func main() {
ages := map[string]int{
"Аня": 30,
"Борис": 25,
}
ages["Вера"] = 28 // добавление
fmt.Println(ages["Аня"])
fmt.Println(len(ages))
}Вывод:
30 3
Идиома проверки ok
Если запросить отсутствующий ключ, map вернёт нулевое значение типа — и вы не отличите «ключа нет» от «значение равно нулю». Поэтому существует форма с двумя результатами: значение и булев флаг наличия.
package main
import "fmt"
func main() {
stock := map[string]int{"яблоки": 0}
n := stock["груши"] // 0, но ключа нет
fmt.Println(n)
if v, ok := stock["яблоки"]; ok {
fmt.Println("яблоки есть, остаток:", v)
}
if _, ok := stock["груши"]; !ok {
fmt.Println("груш нет в каталоге")
}
}Вывод:
0 яблоки есть, остаток: 0 груш нет в каталоге
Эта идиома v, ok := m[key] — стандартный способ проверить наличие ключа. Запомните её: она встречается в Go-коде постоянно.
Удаление
Встроенная функция delete убирает ключ. Если ключа не было — ничего не произойдёт, ошибки не будет.
package main
import "fmt"
func main() {
m := map[string]int{"a": 1, "b": 2}
delete(m, "a")
fmt.Println(m, len(m))
}Вывод:
map[b:2] 1
Перебор и порядок
map перебирают через for range. Важная особенность: порядок обхода не определён и меняется от запуска к запуску — Go намеренно рандомизирует его, чтобы код не полагался на порядок. Нужен порядок — соберите ключи в срез и отсортируйте.
for key, value := range ages {
fmt.Println(key, value)
}Итог
- map создают через литерал или
make; запись в nil-map паникует. - Идиома
v, ok := m[key]отличает отсутствие ключа от нулевого значения. deleteубирает ключ; порядок обхода map не определён.