programowanieProgramista Go

Jakie typy danych w Go są uznawane za porównywalne (comparable) i co się dzieje przy próbie porównania typów nieporównywalnych? Jak to wpływa na użycie map i set?

Zdaj rozmowy kwalifikacyjne z asystentem AI Hintsage

Odpowiedź

W Go zmienne można porównywać ze sobą operatorem == lub używać ich jako kluczy w mapach tylko wtedy, gdy ich typ jest porównywalny. Do porównywalnych należą:

  • Wszystkie typy liczbowe (int, float64, ...)
  • Znaki (string, rune)
  • Wskaźniki
  • Kanały
  • Interfejsy, jeśli ich wartości są porównywalne
  • Tablice (array) i struktury, jeśli wszystkie ich pola są porównywalne

Slices, mapy, funkcje — są nieporównywalne!

Próba porównania takich wartości prowadzi do błędu kompilacji. Na przykład:

var a = []int{1,2,3} var b = []int{1,2,3} printf("%v", a==b) // błąd kompilacji: slice można porównywać tylko z nil

Aby używać wartości jako klucza w mapie, musi ona być porównywalna. Jeśli typ nie jest zgodny — błąd kompilacji.

Pytanie z haczykiem

"Czy mogą dwie struktury być uznawane za porównywalne, jeśli tylko część ich pól jest nieporównywalna?"

Wielu odpowiada "tak", ale to nieprawda. Jeśli choć jedno pole struktury jest nieporównywalne (na przykład, to slice lub map), cała struktura staje się nieporównywalna.

Przykład:

type T struct { A int S []string } var t1, t2 T t1 == t2 // błąd kompilacji: Slices są nieporównywalne

Przykłady rzeczywistych błędów z powodu braku znajomości subtelności tematu


Historia

Programista próbował używać slice jako klucza w mapie, aby buforować wyniki obliczeń, co powodowało błąd kompilacji. Zmieniono to na string z wyraźnym serializatorem — problem został rozwiązany.


Historia

Przy dodawaniu nowego pola (typu slice) do struktury używanej jako klucz w słowniku, nagle projekt przestał się kompilować. Powód: struktura stała się nieporównywalna, ale nikt nie spodziewał się, że to wpłynie na zagnieżdżone struktury.


Historia

Aby stworzyć zbiór (set) ze strukturami z slice'ami w środku, próbowano użyć mapy. Nie rozumiejąc zasad porównania, napotkano wiele błędów w czasie wykonywania podczas próby porównania elementów, ale przyczyna tkwiła w niemożności skompilowania ich z takim kluczem.