Nel linguaggio Go è implementata la tipizzazione statica rigorosa. Questo significa che il tipo di ogni variabile è noto al momento della compilazione e il compilatore non consente di eseguire operazioni con tipi incompatibili.
Ci sono due tipi di conversione dei tipi:
Esempio di conversione esplicita:
var i int = 42 var f float64 = float64(i)
Esempio di type assertion:
var i interface{} = "hello" s, ok := i.(string) if ok { fmt.Println("Valore String:", s) } else { fmt.Println("i non è una string") }
La conversione è possibile solo tra tipi di base compatibili (int → float64, rune → int32, ma string → int non è possibile).
L'interfaccia{} può contenere un valore nil e come controllare correttamente se la variabile di tipo interfaccia è davvero nil?
Una trappola comune è confrontare l'interfaccia che contiene un valore nil con nil direttamente:
var err error = nil var i interface{} = err fmt.Println(i == nil) // Aspettano true, ma sarà false!
Il modo corretto è:
Controllare che sia l'interfaccia stessa sia il valore interno siano nil:
if i == nil || reflect.ValueOf(i).IsNil() { fmt.Println("i è davvero nil") }
Storia
Nel progetto del backend, uno sviluppatore cercava di gestire vari errori tramite interface{}, confrontandoli con nil. Di conseguenza, l'errore non poteva essere rilevato correttamente — si verificavano bug nascosti e una logica di ritorno degli errori errata al cliente.
Storia
La migrazione tra float64 e int senza cast esplicito causava una perdita di dati silenziosa: i valori venivano arrotondati o trasferiti in modo scorretto poiché il compilatore Go richiede una conversione esplicita per tali operazioni.
Storia
Nella deserializzazione dei valori delle interfacce quando si lavora con map[string]interface{} (ad esempio, da JSON) tipi inaspettati di numeri (float64) portavano a panico durante l'uso di type assertion senza il controllo aggiuntivo ok – il servizio si bloccava a causa di un errore di runtime.