Что будет при работе с map без инициализации в Go и почему возникает паника
Что проверяют
Знаете ли вы, что чтение из нулевой карты безопасно, а запись нет, и понимаете ли причину.
Как отвечать
Объявленная, но не инициализированная карта равна nil:
var m map[string]int // nil, не пустая картаЧто с ней можно:
- чтение работает и возвращает нулевое значение типа:
m["a"]даст 0, а форма с двумя значениями вернёт0, false; len(m)вернёт 0;rangeотработает ноль итераций;delete(m, k)ничего не сделает и не упадёт.
Что нельзя: запись. m["a"] = 1 вызывает панику assignment to entry in nil map.
Причина в реализации. Переменная типа map это указатель на структуру hmap, где лежат массив корзин, счётчик элементов и хеш-начало. У нулевой карты этот указатель пуст, самой структуры нет. Чтение обходится без неё: рантайм видит nil и сразу возвращает нулевое значение. А запись обязана положить пару в корзину, значит нужны и структура, и массив корзин, и рост при заполнении. Создавать их молча рантайм не станет, потому что карта передаётся по значению указателя, и такое создание не было бы видно вызывающему коду. Поэтому вместо тихой ошибки выбран явный сбой.
Инициализация: m := make(map[string]int) или литерал map[string]int{}. Внутри структуры карта тоже нулевая, пока её не создали, и это частая причина паники: s := MyStruct{} даёт поле-карту равным nil.
Тот же принцип у слайса работает иначе: append к нулевому слайсу корректен, потому что возвращает новый слайс.
Где спотыкаются
Считают, что объявленная карта уже пустая и готова к записи.
Забывают инициализировать поле-карту в конструкторе структуры.
Ждут паники при чтении.
Переносят логику со слайса, где append к nil допустим.