Beherrschen von Go's Kern-Datentypen: Ganzzahlen, Gleitkommazahlen, Booleans und Strings
Lukas Schneider
DevOps Engineer · Leapcell

Go, bekannt für seine Einfachheit, Effizienz und starke Typisierung, stützt sich stark auf seine grundlegenden Datentypen, um robuste Anwendungen zu erstellen. Im Gegensatz zu dynamisch typisierten Sprachen erfordert Go, dass Sie den Typ einer Variablen explizit definieren, was dazu beiträgt, Fehler frühzeitig zu erkennen und die Lesbarkeit des Codes zu verbessern. Dieser Artikel befasst sich mit Go's vier primären integrierten Datentypen: Ganzzahlen, Gleitkommazahlen, Booleans und Strings und bietet ein umfassendes Verständnis ihrer Eigenschaften und Verwendung mit praktischen Codebeispielen.
Ganzzahlen: Das Fundament des Zählens
Ganzzahlen in Go stellen ganze Zahlen dar, sowohl positive als auch negative, ohne jegliche Bruchteile. Go bietet eine Vielzahl von Ganzzahltypen, die sich hauptsächlich in ihrer Größe (Anzahl der Bits) und darin unterscheiden, ob sie vorzeichenbehaftet oder vorzeichenlos sind. Die Wahl des richtigen Ganzzahltyps ist entscheidend für die Speichereffizienz und die Vermeidung von Überlauffehlern.
Vorzeichenbehaftete Ganzzahlen: Können sowohl positive als auch negative Werte darstellen.
int8
: -128 bis 127int16
: -32768 bis 32767int32
: -2.147.483.648 bis 2.147.483.647 (auch alsrune
für Unicode-Codepunkte aliasiert)int64
: -9.223.372.036.854.775.808 bis 9.223.372.036.854.775.807int
: Ein plattformabhängiger vorzeichenbehafteter Ganzzahltyp. Unter 32-Bit-Systemen ist er normalerweise 32-Bit; unter 64-Bit-Systemen ist er 64-Bit. Dies ist der am häufigsten verwendete Ganzzahltyp, wenn die genaue Größe nicht kritisch ist.
Vorzeichenlose Ganzzahlen: Können nur nicht-negative Werte (Null und positiv) darstellen. Dies ermöglicht es ihnen, größere positive Zahlen im gleichen Bitbereich im Vergleich zu ihren vorzeichenbehafteten Gegenstücken zu speichern.
uint8
: 0 bis 255 (auch alsbyte
für Rohdaten aliasiert)uint16
: 0 bis 65535uint32
: 0 bis 4.294.967.295uint64
: 0 bis 18.446.744.073.709.551.615uint
: Ein plattformabhängiger vorzeichenloser Ganzzahltyp, der die Größe vonint
widerspiegelt.uintptr
: Ein vorzeichenloser Ganzzahltyp, der groß genug ist, um die uninterpretierten Bits eines Zeigerwerts zu speichern. Wird im Anwendungscode selten direkt verwendet.
Ganzzahl-Deklaration und -Initialisierung:
package main import "fmt" func main() { // Explizite Typdeklaration var age int = 30 var population int64 = 8_000_000_000 // Unterstriche zur besseren Lesbarkeit (Go 1.13+) var score uint8 = 250 // Maximalwert für uint8 ist 255 var temperature int = -5 // Kurze Variablendeklaration (Typ abgeleitet) count := 100 id := uint(12345) fmt.Printf("Alter: %d (Typ: %T)\n", age, age) fmt.Printf("Bevölkerung: %d (Typ: %T)\n", population, population) fmt.Printf("Punktzahl: %d (Typ: %T)\n", score, score) fmt.Printf("Temperatur: %d (Typ: %T)\n", temperature, temperature) fmt.Printf("Anzahl: %d (Typ: %T)\n", count, count) fmt.Printf("ID: %d (Typ: %T)\n", id, id) // Beispiel für Ganzzahlüberlauf (führt zu einem Kompilierungsfehler, wenn der Wert den Typbereich überschreitet) // var tooBig uint8 = 300 // Kompilierungsfehler: Konstante 300 überläuft uint8 }
Bei arithmetischen Operationen erfordert Go, dass Operanden vom gleichen Typ sind. Eine explizite Typumwandlung ist erforderlich, wenn die Typen unterschiedlich sind.
package main import "fmt" func main() { var a int = 10 var b int64 = 20 // c := a + b // Kompilierungsfehler: Inkompatible Typen int und int64 // Korrekter Weg: Typumwandlung c := int64(a) + b d := a + int(b) fmt.Printf("Ergebnis c: %d (Typ: %T)\n", c, c) fmt.Printf("Ergebnis d: %d (Typ: %T)\n", d, d) }
Gleitkommazahlen: Umgang mit Dezimalzahlen
Gleitkommazahlen in Go werden verwendet, um Zahlen mit Bruchteilen darzustellen. Sie sind unerlässlich für Berechnungen, die Genauigkeit erfordern, wie z. B. wissenschaftliche Berechnungen, Finanzanwendungen und Grafiken. Go bietet zwei Gleitkommazahltypen:
float32
: Eine einfach präzise Gleitkommazahl, typischerweise 32-Bit. Bietet weniger Genauigkeit, benötigt aber weniger Speicher.float64
: Eine doppelt präzise Gleitkommazahl, typischerweise 64-Bit. Bietet höhere Genauigkeit und ist der Standardtyp, der für Gleitkommazahlenliterale abgeleitet wird.
Gleitkommazahl-Deklaration und -Initialisierung:
package main import "fmt" func main() { var pi float32 = 3.14159 var gravity float64 = 9.80665 var price = 19.99 // Abgeleitet als float64 fmt.Printf("Pi: %f (Typ: %T)\n", pi, pi) fmt.Printf("Schwerkraft: %f (Typ: %T)\n", gravity, gravity) fmt.Printf("Preis: %f (Typ: %T)\n", price, price) // Gleitkomma-Arithmetik result := pi * float32(gravity) // Explizite Umwandlung zur Durchführung der Operation fmt.Printf("Ergebnis der Multiplikation: %f\n", result) // Aufgrund der Art der Gleitkommadarstellung kann ein direkter Gleichheitsvergleich manchmal problematisch sein. x := 0.1 y := 0.2 z := 0.3 fmt.Println("x + y == z?", (x+y == z)) // Wird wahrscheinlich aufgrund von Genauigkeitsproblemen falsch ausgegeben fmt.Printf("x + y = %.17f\n", x+y) fmt.Printf("z = %.17f\n", z) // Bevorzugen Sie den Vergleich mit einem kleinen Epsilon für Gleichheitsprüfungen epsilon := 0.00000001 if (x+y)-z < epsilon && (x+y)-z > -epsilon { fmt.Println("x + y ist ungefähr gleich z") } }
Booleans: Die Logikgatter
Booleans stellen Wahrheitswerte dar und sind grundlegend für den Kontrollfluss in der Programmierung. Eine boolesche Variable kann einen von zwei vordefinierten Werten enthalten: true
oder false
.
Boolean-Deklaration und -Initialisierung:
package main import "fmt" func main() { var isActive bool = true var isLoggedIn = false // Abgeleitet als bool fmt.Printf("Ist aktiv: %t (Typ: %T)\n", isActive, isActive) fmt.Printf("Ist eingeloggt: %t (Typ: %T)\n", isLoggedIn, isLoggedIn) // Bedingte Anweisungen mit Booleans if isActive && !isLoggedIn { fmt.Println("Benutzer ist aktiv, aber nicht eingeloggt.") } result := 10 > 5 // true isEligible := age >= 18 // Annahme: 'age' ist definiert fmt.Printf("10 > 5 ist: %t\n", result) // fmt.Printf("Ist berechtigt: %t\n", isEligible) // Auskommentierung aufheben, wenn 'age' definiert ist }
Booleans werden ausgiebig in if
, else if
, else
-Anweisungen, for
-Schleifenbedingungen und logischen Operationen (&&
für AND, ||
für OR, !
für NOT) verwendet.
Strings: Umgang mit Textdaten
Strings in Go stellen Sequenzen von unveränderlichen Unicode-Zeichen (Runen) dar. Sie sind ein integrierter Typ und aufgrund ihrer Unveränderlichkeit besonders effizient, was eine sichere gemeinsame Nutzung und optimierte Speicherverwaltung ermöglicht.
String-Deklaration und -Initialisierung:
package main import "fmt" func main() { // Doppelpunkte für interpretierte String-Literale var message string = "Hallo, Go!" name := "Alice" greeting := "こんにちは世界" // Unicode-Zeichen sind vollkommen in Ordnung fmt.Printf("Nachricht: %s (Typ: %T)\n", message, message) fmt.Printf("Name: %s (Typ: %T)\n", name, name) fmt.Printf("Gruß: %s (Typ: %T)\n", greeting, greeting) // Rohe String-Literale (Backticks `): interpretieren Inhalt wörtlich, keine Escape-Sequenzen multiLineString := `Dies ist ein mehrzeiliger String. Neue Zeilen und Sonderzeichen wie \t werden wörtlich behandelt.` fmt.Println(multiLineString) // String-Verkettung fullName := name + " Smith" fmt.Println("Vollständiger Name:", fullName) // String-Länge (Anzahl der Bytes) fmt.Printf("Länge von 'message': %d Bytes\n", len(message)) fmt.Printf("Länge von 'greeting': %d Bytes (nicht Runen!)\n", len(greeting)) // Iteration über einen String (nach Runen) fmt.Println("Iteration über 'greeting':") for i, r := range greeting { fmt.Printf("Index: %d, Rune: %c (Unicode-Wert: %U)\n", i, r, r) } // Zugriff auf Zeichen nach Index (byte-weise) fmt.Printf("Erstes Byte von 'message': %c\n", message[0]) // Gibt 'H' aus // fmt.Printf("Erstes Byte von 'greeting': %c\n", greeting[0]) // Gibt für mehrbyteige Runen möglicherweise ein Symbol aus // Direkter Zugriff auf Runen erfordert Vorsicht // Strings sind unveränderlich: // message[0] = 'h' // Kompilierungsfehler: kann nicht auf message[0] zugewiesen werden (Wert vom Typ byte) // Teilstring (Slicing) part := message[0:5] // "Hallo" fmt.Println("Teil-Substring:", part) // String-Vergleich s1 := "apfel" s2 := "banane" s3 := "apfel" fmt.Printf("'apfel' == 'banane': %t\n", s1 == s2) fmt.Printf("'apfel' == 'apfel': %t\n", s1 == s3) }
Go-Strings sind UTF-8-kodiert. Während len()
die Anzahl der Bytes zurückgibt, dekodiert die Iteration mit for range
korrekt UTF-8 und liefert einzelne Unicode-rune
-Werte (int32) zusammen mit ihrem startenden Byte-Index. Diese Unterscheidung ist entscheidend, wenn mit multikulturellen Texten gearbeitet wird.
Fazit
Das Verständnis von Go's grundlegenden Datentypen – Ganzzahlen, Gleitkommazahlen, Booleans und Strings – ist die Grundlage für das Schreiben effektiver Go-Programme. Jeder Typ dient einem bestimmten Zweck, und Go's strenge Typisierung gewährleistet Typsicherheit und vorhersagbares Verhalten. Durch die umsichtige Auswahl des geeigneten Typs können Entwickler robuste, effiziente und lesbare Codes erstellen. Die Beherrschung dieser Grundlagen ist der erste Schritt zur Nutzung von Go's Leistung für eine Vielzahl von Anwendungen, von Systemprogrammierung bis hin zu Webdiensten. Im weiteren Verlauf werden Sie feststellen, dass diese grundlegenden Typen die Bausteine für komplexere Datenstrukturen wie Arrays, Slices, Maps und Structs bilden, die Ihre Go-Entwicklung weiter vorantreiben.