Ответ
В Go ключи в map должны быть сравниваемыми (comparable), то есть поддерживать операции ==
и !=
. Это требование обусловлено тем, что Go использует хеширование и сравнение для эффективного хранения и поиска элементов в map.
Основные типы, которые можно использовать как ключи:
- Все простые типы:
int
,float64
,string
,bool
,complex64
,complex128
и т.д. - Указатели (
*T
) - Каналы (
chan T
) - Интерфейсы (если их динамические типы сравнимы и имеют одинаковый тип и значение)
- Структуры и массивы (если все их поля/элементы сравнимы)
Нельзя использовать:
- Срезы (
[]T
) – их содержимое может меняться, и они не поддерживают операцию сравнения==
. - Функции (
func
) – они не сравнимы. - Map (
map[K]V
) – они не сравнимы. - Структуры или массивы, содержащие несравнимые поля/элементы (например, срез или функцию).
Пример:
m := make(map[[2]int]string) // массив как ключ - ок, так как элементы int сравнимы
m[[2]int{1, 2}] = "value"
type Key struct {
X int
Y string
}
m2 := make(map[Key]bool) // структура как ключ - ок, так как поля int и string сравнимы
m2[Key{X: 1, Y: "test"}] = true
// Пример несравнимого типа (срез внутри структуры)
type InvalidKey struct {
ID int
Tags []string // Срез, делает InvalidKey несравнимой
}
// var _ map[InvalidKey]int // Ошибка компиляции: InvalidKey is not comparable