Коллекции: массивы, срезы и отображения

Map: создание, чтение, запись, удаление и проверка ключа

Содержание курса

В предыдущих уроках мы работали со срезами: добавляли элементы, копировали базовый массив, удаляли по индексу. Срез хорош, когда важен порядок и доступ по позиции. Но если нужно быстро найти значение по имени — по слову, идентификатору, коду — срез заставляет перебирать всё подряд. Map решает именно эту задачу: O(1) доступ по произвольному ключу.

Тип map[K]V, литерал и make: инициализация и nil-паника

Тип map[string]int читается буквально: отображение из string в int. Ключом может быть любой сравниваемый тип — строка, число, булево, указатель; срез или другая map ключом быть не могут.

Создать map можно двумя способами. Первый — литерал с начальными данными:

scores := map[string]int{
    "alice": 42,
    "bob":   17,
}

Второй — make, когда начальных данных нет:

scores := make(map[string]int)

Оба варианта дают готовую к работе map. Разница лишь в том, есть ли начальные пары.

А вот что будет, если просто объявить переменную без инициализации:

var scores map[string]int
scores["alice"] = 42 // panic: assignment to entry in nil map

Нулевое значение map — nil. Читать из nil-map можно (вернётся нулевое значение типа), но запись вызывает panic немедленно. Это принципиально отличается от nil-среза, в который нельзя записать через индекс, но можно передать в append.

Практическое правило: перед любой записью map должна быть инициализирована — либо литералом, либо через make. Выбор между ними прост: если начальные пары известны заранее — литерал; если map наполняется в процессе работы программы — make.