В Go переменные можно сравнивать между собой оператором == или использовать их в качестве ключа map только если их тип — comparable. К сравнимым относятся:
int, float64, ...)string, rune)Срезы, мапы, функции — несравнимы!
Попытка сравнить такие значения приводит к ошибке компиляции. Например:
var a = []int{1,2,3} var b = []int{1,2,3} printf("%v", a==b) // compile error: slice can only be compared to nil
Для использования значения как ключа в map оно обязательно должно быть сравнимым. Если тип не соответствует — ошибка компиляции.
"Могут ли две структуры считаться сравнимыми, если только часть их полей несравнима?"
Многие отвечают "да", но это неверно. Если хотя бы одно поле структуры несравнимо (например, это slice или map), вся структура становится несравнимой.
Пример:
type T struct { A int S []string } var t1, t2 T t1 == t2 // compile error: Slices are not comparable
История
Разработчик попытался использовать слайс как ключ к map, чтобы кэшировать результаты вычислений, что вызывало ошибку компиляции. Заменили на string с явным сериализатором — проблема решилась.
История
При добавлении нового поля (типа slice) в структуру, используемую как ключ словаря, внезапно перестал собираться проект. Причина: теперь структура стала несравнимой, но никто не ожидал, что это распространится вглубь вложенных структур.
История
Чтобы сделать множество (set) по структурам с слайсами внутри, пытались использовать map. Не разобравшись в правилах сравнения, получили множество runtime ошибок при попытке сравнить элементы, но причина крылась в невозможности их компилировать с таким ключом.