Ответ
Ключом в map
в Go может быть любой тип данных, для которого определена операция сравнения на равенство (==
) и неравенство (!=
). Такие типы в спецификации языка называются сравниваемыми (comparable).
Это требование необходимо, потому что map
— это хеш-таблица. Для работы ей нужно уметь:
- Вычислять хеш от ключа, чтобы определить его местоположение (бакет).
- Сравнивать ключи на равенство для разрешения коллизий (когда у разных ключей одинаковый хеш).
Какие типы можно использовать в качестве ключа:
- Все числовые типы (
int
,float64
и т.д.) - Строки (
string
) - Булевы значения (
bool
) - Указатели (
*T
) - Каналы (
chan T
) - Интерфейсы (только если динамический тип, хранящийся в интерфейсе, является сравниваемым)
- Структуры (
struct
), если все их поля являются сравниваемыми типами. - Массивы (
[N]T
), если их элементы (T
) являются сравниваемыми типами.
Какие типы использовать НЕЛЬЗЯ:
Эти типы не поддерживают операцию сравнения ==
.
- Слайсы (
[]T
) - Карты (
map[K]V
) - Функции (
func()
)
Пример:
// Корректные ключи
m1 := make(map[string]int) // Строка
m2 := make(map[int]bool) // Целое число
type Point struct{ X, Y int }
m3 := make(map[Point]string) // Структура со сравниваемыми полями
// Некорректные ключи
// m4 := make(map[[]int]string) // Ошибка компиляции: invalid map key type []int
// m5 := make(map[map[string]int]bool) // Ошибка компиляции: invalid map key type map[string]int
Частый кейс: Если нужно использовать слайс байт ([]byte
) в качестве ключа, его можно преобразовать в строку: string(myByteSlice)
.