In der Go-Sprache wird eine statische strenge Typisierung implementiert. Das bedeutet, dass der Typ jeder Variable zur Compile-Zeit bekannt ist und der Compiler keine Operationen mit inkompatiblen Typen erlaubt.
Es gibt zwei Arten der Typumwandlung:
Beispiel für eindeutige Typumwandlung:
var i int = 42 var f float64 = float64(i)
Beispiel für Type Assertion:
var i interface{} = "hello" s, ok := i.(string) if ok { fmt.Println("Stringwert:", s) } else { fmt.Println("i ist kein String") }
Eine Umwandlung ist nur zwischen kompatiblen Basistypen möglich (int → float64, rune → int32, aber string → int ist nicht möglich).
Kann interface{} einen Nil-Wert speichern, und wie überprüft man korrekt, dass eine Variable vom Typ Schnittstelle tatsächlich nil ist?
Eine häufige Falle ist, die Schnittstelle, die einen Nil-Wert enthält, direkt mit nil zu vergleichen:
var err error = nil var i interface{} = err fmt.Println(i == nil) // Erwartet true, wird aber false sein!
Der richtige Weg:
Überprüfen, dass sowohl die Schnittstelle nil ist als auch der enthaltene Wert nil:
if i == nil || reflect.ValueOf(i).IsNil() { fmt.Println("i ist tatsächlich nil") }
Geschichte
Im Backend-Projekt versuchte ein Entwickler, verschiedene Fehler über interface{} zu behandeln und verglich sie mit nil. Infolgedessen konnte der Fehler nicht korrekt erkannt werden – es traten versteckte Bugs und falsche Logik bei der Fehlerweitergabe an den Client auf.
Geschichte
Die Migration zwischen float64 und int ohne expliziten Cast verursachte einen stillen Datenverlust: Werte wurden gerundet oder inkorrekt übertragen, da der Go-Compiler eine explizite Umwandlung für solche Operationen verlangt.
Geschichte
Bei der Deserialisierung von Schnittstellenwerten während der Arbeit mit map[string]interface{} (zum Beispiel aus JSON) führten unerwartete Zahlenarten (float64) zu Panik bei der Verwendung von Type Assertion ohne zusätzliche Überprüfung von ok – der Service stürzte aufgrund eines Laufzeitfehlers ab.