1 Einführung in die Go-Sprachdatentypen

In der Go-Sprache sind Datentypen das Fundament der Programmierung und bestimmen die Form der Daten, die Variablen speichern können. Die von der Go-Sprache bereitgestellten Grunddatentypen lassen sich hauptsächlich in die folgenden Kategorien einteilen:

Datentyp Beschreibung Speicherbedarf
bool Boolescher Typ, zur Speicherung von Wahr oder Falsch 1 Byte
int, uint Vorzeichenbehaftete und vorzeichenlose Ganzzahlen, Standardgröße abhängig von der Systemplattform 4 oder 8 Bytes
int8, uint8 8-Bit vorzeichenbehaftete und vorzeichenlose Ganzzahlen 1 Byte
int16, uint16 16-Bit vorzeichenbehaftete und vorzeichenlose Ganzzahlen 2 Bytes
int32, uint32 32-Bit vorzeichenbehaftete und vorzeichenlose Ganzzahlen 4 Bytes
int64, uint64 64-Bit vorzeichenbehaftete und vorzeichenlose Ganzzahlen 8 Bytes
float32 32-Bit Gleitkommazahl 4 Bytes
float64 64-Bit Gleitkommazahl 8 Bytes
complex64 Komplexe Zahl mit 32-Bit Real- und Imaginärteilen 8 Bytes
complex128 Komplexe Zahl mit 64-Bit Real- und Imaginärteilen 16 Bytes
byte Ähnlich wie uint8 1 Byte
rune Ähnlich wie int32, stellt einen Unicode-Codepunkt dar 4 Bytes
string Zeichenkettentyp Abhängig von der Länge der Zeichenkette
error Fehler-Schnittstelle, zur Rückgabe von Fehlerinformationen Keine feste Größe

Diese Typen können je nach Bedarf für unterschiedliche Zwecke wie numerische Berechnungen, Textverarbeitung oder logische Steuerung ausgewählt werden.

2 Ganzzahldatentypen

2.1 Überblick über Ganzzahltypen

Die Go-Sprache verfügt über mehrere integrierte Ganzzahltypen, die wie folgt eingeteilt sind:

  • Vorzeichenbehaftete Ganzzahlen: int8, int16, int32 (oder rune), int64 und int
  • Vorzeichenlose Ganzzahlen: uint8 (oder byte), uint16, uint32, uint64 und uint

Die Größen von int und uint betragen auf 32-Bit-Systemen 4 Bytes und auf 64-Bit-Systemen 8 Bytes. Die Wertebereiche der Ganzzahldatentypen sind in der folgenden Tabelle aufgeführt:

Typ Wertebereich
int8 -128 bis 127
uint8 0 bis 255
int16 -32768 bis 32767
uint16 0 bis 65535
int32 -2147483648 bis 2147483647
uint32 0 bis 4294967295
int64 -9223372036854775808 bis 9223372036854775807
uint64 0 bis 18446744073709551615

2.2 Verwendung von Ganzzahlvariablen

Die grundlegende Syntax zur Deklaration einer Ganzzahlvariablen lautet wie folgt:

var variablenname datentyp = anfangswert

Beispielcode:

package main
import "fmt"

func main() {
    var a int = 10 // Vorzeichenbehaftete Ganzzahlvariable
    var b uint = 20 // Vorzeichenlose Ganzzahlvariable
    var c int8 = -128 // Kleinstmöglicher int8-Wert
    fmt.Println(a, b, c)
}

2.3 Ganzzahl-Operationen

Die Go-Sprache unterstützt gängige arithmetische Operatoren wie Addition (+), Subtraktion (-), Multiplikation (*), Division (/) und Modulo (%), sowie bitweise Operatoren wie bitweises UND (&), ODER (|), XOR (^), Linksverschiebung (<<) und Rechtsverschiebung (>>).

package main
import "fmt"

func main() {
    x := 10
    y := 3

    // Arithmetische Operationen
    fmt.Println(x + y) // Addition
    fmt.Println(x - y) // Subtraktion
    fmt.Println(x * y) // Multiplikation
    fmt.Println(x / y) // Division
    fmt.Println(x % y) // Modulo

    // Bitweise Operationen
    fmt.Println(x & y)  // Bitweises UND
    fmt.Println(x | y)  // Bitweises ODER
    fmt.Println(x ^ y)  // Bitweises XOR
    fmt.Println(x << 1) // Linksverschiebung um 1
    fmt.Println(x >> 1) // Rechtsverschiebung um 1
}

3 Gleitkommazahldatentypen

3.1 Überblick über Fließkomma Datentypen

In der Go-Sprache umfassen die Fließkommazahlen die Typen float32 und float64, die 32-Bit- und 64-Bit-Fließkomma-Daten entsprechen. Im Allgemeinen wird empfohlen, float64 zu verwenden, da es einen größeren Bereich und eine genauere Präzision bietet.

  • float32 hat ungefähr 23 signifikante Bits und bietet ungefähr 7 Dezimalstellen Präzision.
  • float64 hat ungefähr 52 signifikante Bits und bietet ungefähr 16 Dezimalstellen Präzision.

3.2 Verwendung von Fließkommavariablen

Fließkommavariablen können direkt durch die Bereitstellung von Literalen oder durch Verwendung des var-Schlüsselworts deklariert werden:

package main
import "fmt"

func main() {
    var f1 float32 = 3.14 // Explizites Angeben des float32-Typs
    f2 := 3.14            // Automatisch als float64-Typ inferiert
    fmt.Println(f1, f2)
}

3.3 Fließkommazahlen und Probleme

Fließkommazahlen können zu Präzisionsverlust führen. Die Durchführung von Operationen mit sehr hoher Präzision ist ein häufiges Problem, insbesondere beim Subtrahieren von zwei sehr nahen Zahlen.

package main
import "fmt"

func main() {
    f1 := .1
    f2 := .2
    f3 := f1 + f2
    fmt.Println(f3) // Die Ausgabe ist möglicherweise nicht das erwartete .3 aufgrund von Präzisionsproblemen

    // Beheben von Präzisionsproblemen mit formatierter Ausgabe
    fmt.Printf("%.1f\n", f3) // Ausgabe korrigiert auf .3
}

4 Boolescher Datentyp

4.1 Überblick über den booleschen Datentyp

Boolesch ist der einfachste Datentyp und kann nur die Werte true (wahr) und false (falsch) haben. Er nimmt eine sehr wichtige Stellung in bedingten Anweisungen und Schleifensteuerstrukturen ein.

4.2 Verwendung von booleschen Variablen

Deklaration und Verwendung von booleschen Variablen:

package main
import "fmt"

func main() {
    var success bool = true
    var fail bool = false
    fmt.Println("Operation erfolgreich:", success)
    fmt.Println("Operation fehlgeschlagen:", fail)
}

Boolesche Werte werden häufig in bedingten Anweisungen verwendet:

package main
import "fmt"

func main() {
    a := 10
    b := 20
    fmt.Println("a == b:", a == b) // false
    fmt.Println("a < b:", a < b)   // true
}

5 Zeichenkettendatentyp

5.1 Übersicht über Zeichenkettendatentypen

Eine Zeichenkette ist eine Sammlung von Zeichen. In der Go-Sprache sind Zeichenketten unveränderlich. Jede Zeichenkette besteht aus zwei Teilen: einem Zeiger auf das zugrunde liegende Byte-Array und einer Länge. Zeichenketten können beliebige Daten, einschließlich Bytes, enthalten.

5.2 Verwendung von Zeichenkettenvariablen

Zeichenkettenvariablen werden normalerweise mit doppelten Anführungszeichen " erstellt, aber Sie können auch Backticks ` verwenden, um mehrzeilige Zeichenketten zu erstellen:

package main
import "fmt"

func main() {
    var s1 string = "Hallo"
    s2 := "Welt"
    s3 := `Das ist eine 
    mehrzeilige 
    Zeichenkette`
    fmt.Println(s1)
    fmt.Println(s2)
    fmt.Println(s3)
}

Sobald eine Zeichenkette erstellt ist, kann ihr Inhalt nicht geändert werden. Die folgende Operation ist unzulässig und führt zu einem Kompilierungsfehler:

s := "Hallo"
s[] = 'H` // Kompilierungsfehler: Zeichenketteninhalt ist unveränderlich

5.3 Zeichenkettenoperationen

Zeichenketten sind in der Programmierung sehr verbreitet und wichtig. Die Go-Sprache bietet eine umfangreiche Reihe von integrierten Funktionen zur Zeichenkettenmanipulation. Hier sind einige häufig verwendete Operationen.

5.3.1 Zeichenkettenverkettung

In der Go-Sprache können Sie das Pluszeichen (+) verwenden, um Zeichenketten zu verketten, was die direkteste Methode ist. Wenn Sie jedoch häufig mehrere Zeichenketten verketten, wird empfohlen, strings.Builder für eine bessere Leistung zu verwenden.

package main

import (
    "fmt"
    "strings"
)

func main() {
    // Verkettung von Zeichenketten mit +
    hallo := "Hallo, "
    welt := "Welt!"
    ergebnis := hallo + welt
    fmt.Println(ergebnis) // Ausgabe: Hallo, Welt!

    // Verkettung von Zeichenketten mit strings.Builder
    var sb strings.Builder
    sb.WriteString("Hallo, ")
    sb.WriteString("Welt!")
    fmt.Println(sb.String()) // Ausgabe: Hallo, Welt!
}

5.3.2 Zeichenfolgenzerlegung

Die Zeichenfolgenzerlegung kann mithilfe der Funktion strings.Split durchgeführt werden, die die Zeichenfolge anhand des angegebenen Trennzeichens in ein Slice aufteilt.

package main

import (
    "fmt"
    "strings"
)

func main() {
    // Definiere eine Zeichenfolge
    satz := "Go ist eine Open-Source-Programmiersprache"

    // Teile die Zeichenfolge am Leerzeichen auf
    wörter := strings.Split(satz, " ")
    for _, wort := range wörter {
        fmt.Printf("%s\n", wort)
    }
    // Ausgabe:
    // Go
    // ist
    // eine
    // Open-Source-Programmiersprache
}

5.3.3 Indexzugriff

In Go ist eine Zeichenfolge eine unveränderliche Sequenz von Bytes. Sie können Indizes verwenden, um auf bestimmte Bytes in einer Zeichenfolge zuzugreifen. Es ist jedoch wichtig zu beachten, dass eine Zeichenfolge mehrere Bytes enthalten kann (wie z.B. UTF-8-codierte Zeichen), und ein direkter Indexzugriff möglicherweise nicht das erwartete einzelne Zeichen ergibt.

package main

import "fmt"

func main() {
    s := "Hallo, 世界"
    for i := range s {
        fmt.Printf("%d: %x\n", i, s[i])
    }
    // Hinweis: Dies gibt die hexadezimale Darstellung der Bytes aus, nicht die Zeichen selbst
}

Um durch die Zeichenfolge nach Zeichen zu iterieren, können Sie die range-Schleife verwenden.

package main

import "fmt"

func main() {
    s := "Hallo, 世界"
    for index, runeValue := range s {
        fmt.Printf("%d: %U '%c'\n", index, runeValue, runeValue)
    }
    // Ausgabe: Index, Unicode-Kodierung und das Zeichen selbst für jedes Zeichen
}

5.3.4 Länge abrufen

Die Funktion len kann die Länge einer Zeichenfolge, d.h. die Länge der zugrunde liegenden Byte-Sequenz, ermitteln. Für UTF-8-Zeichenfolgen sollten Sie die Funktion utf8.RuneCountInString verwenden, wenn Sie die Anzahl der Zeichen (runes) ermitteln müssen. Dies kann mehrbyte Zeichen korrekt verarbeiten.

package main

import (
    "fmt"
    "unicode/utf8"
)

func main() {
    s := "Hallo, 世界"
    fmt.Println("Bytelänge:", len(s)) // Ausgabe der Bytelänge
    fmt.Println("Runenlänge:", utf8.RuneCountInString(s)) // Ausgabe der Zeichenlänge
}

Aus dem obigen Beispiel wird ersichtlich, dass die Go-Sprache reichhaltige Bibliotheksfunktionen für Zeichenfolgenoperationen bietet, was die Durchführung verschiedener Zeichenfolgenverarbeitungsaufgaben vereinfacht. Es ist wichtig, beim Codieren auf den Unterschied zwischen Bytes und Zeichen zu achten, insbesondere bei der Bearbeitung von nicht-ASCII-Zeichensätzen.