In Go gibt es zwei Arten von Konstanten – untyped (nicht typisierte) und typed (typisierte). Historisch ist dies auf den Wunsch der Sprache zurückzuführen, die Typsysteme flexibel und sicher zu gestalten, sodass der Compiler Fehler bereits zur Kompilierzeit erkennen kann und Typumwandlungen nur dort zulässt, wo dies zulässig ist.
Problem entsteht, wenn der Programmierer diese zwei Kategorien nicht unterscheidet und sich auf das Verhalten der Konstante verlässt, ohne die Typanforderungen in Funktions- und Schnittstellendeklarationen zu berücksichtigen. Dies kann zu Fehlern bei der Typumwandlung, unerwarteten Kompilierungsfehlern oder unerwarteter „sprunghafter“ Kompatibilität beim Funktionsaufruf führen.
Lösung besteht im klaren Verständnis:
const x int = 42) ist die weitere Verwendung dieser Konstante auf den angegebenen Typ beschränkt.Code-Beispiel:
const Pi = 3.14 // untyped const Answer int64 = 42 // typed func printInt(a int) { fmt.Println(a) } func main() { printInt(Pi) // Fehler: Pi ist kein int (aber kann explizit umgewandelt werden) printInt(int(Pi)) // Ok printInt(Answer) // Ok, da Answer bereits int64 ist und int64 zu int eine explizite Umwandlung ist }
Wichtige Merkmale:
Kann man untyped Konstanten mit float-Werten ohne Umwandlung einer int-Variable zuweisen?
Nein. Obwohl untyped Konstanten in Ausdrücke unterschiedlicher Typen eingesetzt werden können, führt der Versuch, eine float-Konstante einer int-Variable zuzuweisen, zu einem Kompilierungsfehler. Eine explizite Umwandlung ist erforderlich:
const Pi = 3.14 var x int = Pi // Der Compiler gibt einen Fehler aus var y int = int(Pi) // Ok
Erhält die untyped Konstante ihren Typ bei der ersten Zuweisungsoperation?
Nein, die Konstante erhält keinen Typ, bis sie in einem Kontext eingesetzt wird, in dem ein bestimmter Typ erwartet wird, oder bis sie explizit deklariert wird. Andernfalls bleibt sie untyped.
Kann man große numerische Konstanten mit untyped Typen zur Initialisierung kleinerer Variablen verwenden, wenn die Werte passen?
Ja, wenn der Betrag innerhalb des Zieltyps liegt. Andernfalls gibt der Compiler einen Überlauf-Fehler aus.
Beispiel:
const Big = 1 << 62 var x int32 = Big // Fehler: Big passt nicht in int32 var y int64 = Big // Ok
In einem komplexen Finanzprojekt haben Entwickler eine Reihe von Konstanten (Zinsen, Koeffizienten) als untyped deklariert. Eines Tages verlangten einige Funktionen float32 anstelle von float64. Die automatische Typanpassung führte zu einem Verlust an Genauigkeit bei Berechnungen, was nicht sofort bemerkt wurde.
Vorteile:
Nachteile:
In einem anderen Teil des Systems sind alle Konstanten durch explizite Typdeklaration definiert, und die Umwandlungen erfolgen explizit:
const Discount float64 = 0.05
Vorteile:
Nachteile: