Какой тип будет у переменной map[string]string без инициализации в Go
Что проверяют
Знаете ли вы разницу между типом и нулевым значением и что именно можно делать с nil-map. Следом обычно просят показать, какая операция вызовет панику, и спрашивают, чем nil-map отличается от пустой.
Как отвечать
Тип не меняется: переменная var m map[string]string имеет тип map[string]string, типизация в Go статическая. Её значение nil, это нулевое значение для map, так же как для срезов, каналов, указателей и функций.
С nil-map работает всё, кроме записи:
- чтение:
m["a"]вернёт"", аv, ok := m["a"]дастok == false; len(m): ноль;range: ноль итераций, без ошибок;delete(m, "a")иclear(m): ничего не делают;- запись:
m["a"] = "b"вызываетpanic: assignment to entry in nil map.
Инициализация: make(map[string]string), make(map[string]string, n) с подсказкой о размере или литерал map[string]string{}. Сравнивать map можно только с nil, выражение m1 == m2 не скомпилируется.
Разница между nil и пустой map видна в JSON: json.Marshal для nil-map отдаёт null, для пустой {}. Фронтенд может ждать объект и упасть на null. При этом json.Unmarshal в nil-map сам создаст новую map.
Практическое правило: поле-map в структуре инициализируют в конструкторе вроде NewCache(), иначе первый же метод с записью уронит сервис.
Где спотыкаются
Говорят, что nil-map нельзя даже читать. Можно: чтение безопасно и возвращает нулевое значение типа, поэтому nil-map годится как пустой справочник только для чтения.
Думают, что функция может инициализировать переданную ей nil-map. Внутри m = make(...) меняет только локальную копию, у вызывающего переменная останется nil. Нужно вернуть map из функции или передать указатель.
Попадают в ловушку с интерфейсом: nil-map, положенная в переменную типа any, делает интерфейс не равным nil, потому что в нём уже записан тип. Проверка v == nil вернёт false, хотя внутри лежит nil-map.