Map: nil и создание
Миша завёл в памяти индекс filesByID. Ещё до первого использования чтение из него что-то возвращало, а первая же запись уронила сервис. Инцидент зацепил только тестовый контур.
nil-карта допускает чтение, но паникует на записи; создают карту через make или литерал, а сравнить карту можно только с nil.
Nil-карта
var filesByID map[string]int
fmt.Println(filesByID["key"]) // 0 — чтение из nil-карты работает
filesByID["key"] = 1 // panic: assignment to entry in nil map
Нулевое значение карты — nil. Читать из неё можно: отсутствующий ключ возвращает zero value. А запись паникует, потому что за nil-картой не стоит структура данных. Это ловушка для структур, где карту забыли инициализировать.
Создание
filesByID := make(map[string]int)
filesByID["key"] = 1 // теперь работает
filesByID2 := map[string]int{
"a": 1,
"b": 2,
}
make создаёт пустую карту, литерал — карту с начальными значениями. В отличие от слайса, у карты нет понятия ёмкости: make(map[K]V, hint) принимает только подсказку о размере.
Сравнение
Карты сравнивать через == нельзя — ошибка компиляции. Единственное допустимое сравнение — с nil:
var filesByID map[string]int
fmt.Println(filesByID == nil) // true
a := map[string]int{}
b := map[string]int{}
// a == b — ошибка компиляции
Почему: сравнение карт не определено, и это намеренно — нужно было бы сравнивать содержимое, а это дорого и неоднозначно для вложенных структур. Хочешь сравнить содержимое — сравнивай сам, по ключам.
Вы узнаете:
- какие типы могут быть ключами карты
- почему
deleteиз nil-карты безопасен
Проверьте себя
Индекс filesByID объявили, но не создали: var m map[string]int. Что произойдёт при чтении и записи?
Как правильно создать карту?
Можно ли сравнивать две карты через ==?
правильных ответов
nil-карта: читать можно, писать нельзя. Создание — make или литерал; сравнение — только с nil.
10 000 ₽ · 60 минут · онлайн