Historia pytania:
W Go nie ma uniwersalnych kontenerów typu generic map domyślnie — dopiero od Go 1.18 pojawiły się generic, ale do dynamicznych struktur i wcześniej, i obecnie często stosuje się map[string]interface{}, co pozwala przechowywać wartości dowolnego typu pod kluczem tekstowym.
Problem:
Ten wzorzec — odpowiednik słownika/obiektu JSON — występuje wszędzie do serializacji, pracy z middleware, danymi bez określonej struktury (np. parser JSON przez encoding/json). Jednak dostęp do wartości wymaga ręcznego rzutowania typów i ostrożności z niejawnych wartości oraz brakiem kluczy.
Rozwiązanie:
Używać map[string]interface{} tam, gdzie nie jest znana struktura wejściowych danych. Starannie sprawdzać istnienie klucza, rzutować typ (type assertion) tylko po exists-idiom. Lepiej nie trzymać takich map głęboko w logice biznesowej, lecz jako adapter na granicach systemu.
Przykład kodu:
obj := map[string]interface{}{ "int": 42, "str": "cześć", "flag": true, } if v, ok := obj["int"]; ok { n, success := v.(int) if success { fmt.Println(n) } }
Kluczowe cechy:
Czy można bez błędów odczytać wartość po kluczu w map[string]interface{}, jeśli klucz jest nieobecny?
Nie, to da wartość "zero value" (nil) dla interface{}, rzutowanie na konkretny typ spowoduje panikę.
Co się dzieje przy serializacji map[string]interface{} z zagnieżdżonymi slice'ami lub innymi mapami?
Serializacja JSON poprawnie obsłuży strukturę, ale jeśli są typy, które nie są domyślnie obsługiwane (kanały, funkcje), wystąpi błąd przy marshallowaniu.
Czy można porównywać dwie wartości w map[string]interface{} przez ==?
Nie, interface{} można porównywać tylko wtedy, gdy underlying value jest porównywalne. Jeśli trafi tam map lub slice — panic podczas porównania.
W aplikacji cała logika opiera się na obiektach map[string]interface{}, każdy kontroler/usługa przekazuje je głęboko przez wywołania.
Plusy:
Minusy:
Używają map[string]interface{} tylko do pracy z zewnętrznymi interfejsami, danymi wejściowymi/wyjściowymi, a potem przekształcają je w normalne struktury.
Plusy:
Minusy: