Какие типы данных можно использовать в качестве ключей в `map` в Go и почему?

Ответ

В Go ключом в map может быть любой тип данных, для которого определена операция сравнения на равенство (==) и неравенство (!=). Такие типы в спецификации языка называются сравниваемыми (comparable).

Это требование связано с тем, что map внутри реализована как хэш-таблица. Для своей работы ей необходимо:

  1. Вычислять хэш от ключа, чтобы определить его местоположение (бакет).
  2. Сравнивать ключи на равенство для разрешения коллизий (когда несколько ключей имеют одинаковый хэш).

Какие типы можно использовать:

  • Все базовые типы: int, string, bool, float64 и т.д.
  • Указатели.
  • Массивы (но не срезы!).
  • Структуры, если все их поля являются сравниваемыми.
  • Каналы.

Какие типы использовать нельзя:

  • Срезы (slice).
  • Карты (map).
  • Функции (func).

Эти типы не являются сравниваемыми, поэтому их нельзя использовать в качестве ключей.

Пример использования структуры в качестве ключа:

// Определяем структуру, все поля которой (int) являются сравниваемыми
type Point struct {
    X, Y int
}

// Создаем map, где ключ - это структура Point
m := make(map[Point]string)

// Записываем и читаем значения по ключу-структуре
m[Point{10, 20}] = "Точка А"
m[Point{5, -3}] = "Точка Б"

fmt.Println(m[Point{10, 20}]) // Выведет: Точка А