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

Ответ

Ключом в map в Go может быть любой сравниваемый (comparable) тип данных. Сравниваемыми считаются типы, для которых определена операция сравнения == и !=. Эта проверка происходит на этапе компиляции.

Что можно использовать в качестве ключа:

  • Все базовые типы: string, int (и его вариации), float, bool, complex.
  • Указатели и каналы (chan): они сравнимы, сравниваются их адреса в памяти.
  • Структуры, если все их поля являются сравниваемыми типами.
  • Массивы, если их элементы являются сравниваемыми типами.

Что нельзя использовать в качестве ключа:

  • Слайсы (slice): не сравнимы, так как содержат указатель на базовый массив, и их содержимое может меняться, делая сравнение бессмысленным.
  • Карты (map): не сравнимы между собой.
  • Функции: не сравнимы.

Пример:

package main

import "fmt"

type MyStruct struct {
    ID   int
    Name string
}

func main() {
    // --- РАБОТАЮЩИЕ ПРИМЕРЫ ---

    // Строковый ключ
    m1 := make(map[string]int)
    m1["age"] = 30

    // Ключ-массив
    m2 := make(map[[2]int]string)
    m2[[2]int{1, 2}] = "point"

    // Ключ-структура (все поля сравниваемые)
    m3 := make(map[MyStruct]bool)
    m3[MyStruct{ID: 1, Name: "Go"}] = true

    // --- НЕ СКОМПИЛИРУЮТСЯ ---

    // m4 := make(map[[]int]string)      // Ошибка: invalid map key type []int (slice)
    // m5 := make(map[map[int]int]int) // Ошибка: invalid map key type map[int]int (map)
    // m6 := make(map[func()]int)      // Ошибка: invalid map key type func()

    fmt.Println("Примеры успешно отработали")
}