Einführung
Im vorangegangenen Abschnitt haben wir uns mit den gebräuchlichen numerischen Typen befasst. In diesem Abschnitt lernen wir die Zeichentypen in Go kennen.
Lerninhalte:
- ASCII-Kodierung
- UTF-8-Kodierung
- Unicode-Zeichensatz
byterune
ASCII-Kodierung
In der Anfangszeit der Computer wurde das ASCII-Format (American Standard Code for Information Interchange) verwendet. Es stellte Zeichen mit 7 Bit dar und konnte somit 128 (2^7) Zeichen abbilden. Die Zeichen von Bit 0 bis 31 sowie Bit 127 waren nicht darstellbare Steuerzeichen, während die Bits 32 bis 126 die alltäglichen Groß- und Kleinbuchstaben, Zahlen und Satzzeichen repräsentierten. Details finden Sie in der ASCII-Tabelle.
Mit der Weiterentwicklung der Computer entstand der Bedarf, verschiedene Sprachen zu unterstützen. Die ASCII-Kodierung reichte dafür nicht mehr aus. Infolgedessen entwickelten verschiedene Sprachregionen eigene Kodierungsformate, wie zum Beispiel GB2312 für vereinfachtes Chinesisch, EUC-KR für Koreanisch oder KOI8-R für Russisch.
Da es jedoch weltweit unzählige Sprachfamilien gibt, wurde ein einheitliches Format benötigt, das alle Sprachen zusammenführt. Um diesen Bedarf zu decken, wurde Unicode ins Leben gerufen.
Unicode-Zeichensatz
Im Jahr 1991 veröffentlichte das Unicode-Konsortium die erste Version des Unicode-Zeichensatzes. Ziel war es, alle Sprachen in einem einzigen Kodierungsformat zu vereinen, damit Computer weltweit Texte einfacher anzeigen und verarbeiten können, ohne dass Kompatibilitätsprobleme in mehrsprachigen Umgebungen auftreten.
Unicode war jedoch zunächst nur ein Zeichensatz; er definierte zwar die Zeichencodes, aber nicht, wie diese physisch gespeichert werden sollten. Dies führte lange Zeit zu Schwierigkeiten bei der flächendeckenden Einführung, bis das Internet an Bedeutung gewann.
UTF-8-Kodierung
Mit der stetigen Entwicklung des Internets hat sich UTF-8 als Implementierung der Unicode-Kodierung durchgesetzt. Es handelt sich um eine Kodierung mit variabler Länge, was bedeutet, dass verschiedene Symbole in UTF-8 eine unterschiedliche Anzahl an Bytes belegen können.
Englische Buchstaben, die im ASCII-Bereich liegen, werden beispielsweise mit nur 1 Byte dargestellt. Das Zeichen 'y' (Unicode-Wert 121) belegt somit 1 Byte.
Die meisten gängigen chinesischen Schriftzeichen belegen 3 Bytes. So benötigt das Zeichen '实' (Unicode-Wert 23454) beispielsweise 3 Bytes.
Es gibt jedoch auch chinesische Schriftzeichen, die 4 Bytes beanspruchen. Da es über 100.000 chinesische Schriftzeichen gibt, 3 Bytes aber nur etwas mehr als 60.000 Zeichen darstellen können, ist für eine kleine Anzahl von Zeichen ein viertes Byte erforderlich.
Ein weiterer Vorteil der UTF-8-Kodierung ist die Abwärtskompatibilität zu ASCII. Tatsächlich ist ASCII eine Untermenge von UTF-8. Die ersten 128 Zeichen in UTF-8 entsprechen eins zu eins den ASCII-Zeichen. Das bedeutet, dass Software, die ursprünglich für ASCII entwickelt wurde, meist ohne oder mit nur geringfügigen Änderungen weiterverwendet werden kann. Aufgrund dieser Vorzüge wurde UTF-8 schrittweise zum bevorzugten Standardformat.
Die Schöpfer der Programmiersprache Go, Rob Pike und Ken Thompson, haben auch UTF-8 erfunden, weshalb Go eine besondere Affinität zu UTF-8 hat. Go setzt voraus, dass Quellcodedateien in UTF-8-Kodierung gespeichert werden. Bei der Arbeit mit Textzeichen ist UTF-8 die erste Wahl. Zudem bietet die Standardbibliothek zahlreiche Funktionen für die Kodierung und Dekodierung von UTF-8.
byte und rune
byte ist ein Alias für uint8 und belegt ein Byte (8 Bit). Es kann verwendet werden, um alle Zeichen der ASCII-Tabelle darzustellen. Da byte jedoch nur einen begrenzten Wertebereich abdeckt (256 bzw. 2^8), müssen wir für komplexere Zeichen wie chinesische Schriftzeichen den Typ rune verwenden.
Erstellen Sie eine neue Datei namens byte.go und geben Sie den folgenden Code ein:
cd ~/project
touch byte.go
package main
import "fmt"
func main() {
var a byte = 76
fmt.Printf("Value of a: %c\n", a)
var b uint8 = 76
fmt.Printf("Value of b: %c\n", b)
var c byte = 'L'
fmt.Printf("Value of c: %c\n", c)
}
Nach dem Ausführen des Programms wird das folgende Ergebnis ausgegeben:
go run byte.go
Value of a: L
Value of b: L
Value of c: L
Der Platzhalter %c wird zur Ausgabe von Zeichen verwendet. Wie man sieht, liefern die Typen byte und uint8 bei gleichem Wert die gleiche Ausgabe. Ein Blick in die ASCII-Tabelle zeigt, dass der ASCII-Wert für den Buchstaben 'A' 65 ist. Wenn wir den Ganzzahl-Platzhalter %d zur Ausgabe verwenden, erhalten wir ebenfalls 65.
Es wird also deutlich, dass byte in Go äquivalent zum Ganzzahltyp uint8 ist. Das Gleiche gilt für rune, allerdings deckt dieser einen anderen Bereich von Ganzzahlwerten ab.
rune ist ein Alias für int32 und belegt vier Bytes (32 Bit). Er wird verwendet, um zusammengesetzte Zeichen oder Sonderzeichen wie Emojis darzustellen.
Aktualisieren Sie die Datei byte.go mit dem folgenden Code:
package main
import "fmt"
func main() {
var a rune = '😊' // Smile emoji
fmt.Printf("Value of a: %c\n", a)
var b int32 = 9829 // Decimal representation of a Unicode character (Heart symbol)
fmt.Printf("Value of b: %c\n", b)
var c rune = 0x1F496 // Hexadecimal representation of a Unicode character (Sparkling heart emoji)
fmt.Printf("Value of c: %c\n", c)
var d rune = '\u0041' // Unicode character represented by its code point (Capital letter 'A')
fmt.Printf("Value of d: %c\n", d)
var e rune = '\U0001F609' // Unicode character represented by its code point (Winking face emoji)
fmt.Printf("Value of e: %c\n", e)
}
Nach der Ausführung erscheint folgende Ausgabe:
go run byte.go
Hinweis: Führen Sie das Programm im Desktop- oder WebIDE-Terminal aus. Vermeiden Sie die Ausführung im "Terminal Tab" am oberen Rand der LabEx VM.
Value of a: 😊
Value of b: ♥
Value of c: 💖
Value of d: A
Value of e: 😉
- Variable
arepräsentiert das Smiley-Emoji '😊'. - Variable
bwird mit der Dezimaldarstellung eines Unicode-Zeichens (9829) initialisiert, was dem Herzsymbol '♥' entspricht. - Variable
cwird mit der Hexadezimaldarstellung eines Unicode-Zeichens (0x1F496) initialisiert, was dem funkelnden Herz-Emoji '💖' entspricht. - Variable
dstellt den Großbuchstaben 'A' im Unicode-Format\u0041dar. - Variable
estellt das zwinkernde Emoji '😉' im\U-Format mit dem Codepoint0001F609dar.
Wichtiger Hinweis: In Go sind einfache Anführungszeichen und doppelte Anführungszeichen nicht austauschbar. Einfache Anführungszeichen werden für einzelne Zeichen verwendet, während doppelte Anführungszeichen für Strings (Zeichenketten) reserviert sind. Daher müssen bei der Deklaration von byte und rune einfache Anführungszeichen verwendet werden, da sonst ein Fehler auftritt.
Quiz
Lassen Sie uns das Gelernte festigen. Erstellen Sie eine neue Datei namens rune.go und geben Sie den folgenden Code ein. Vervollständigen Sie den Code so, dass die Hexadezimalzahl 0x1F648 der Variablen a zugewiesen wird und das Programm den Wert korrekt ausgibt.
- Anforderungen: Die Datei
rune.gomuss im Verzeichnis~/projectliegen. - Hinweis: Für lange Hexadezimalzahlen muss ein spezifisches Format verwendet werden.
package main
import "fmt"
func main() {
var a rune = 0x1F648
fmt.Printf("The value of a is: %c\n", a)
}
Zusammenfassung
Fassen wir zusammen, was wir in diesem Abschnitt gelernt haben:
- ASCII-Zeichen belegen ein Byte und können 128 verschiedene Zeichen darstellen.
- Die UTF-8-Kodierung ist eine Form des Unicode-Zeichensatzes. Es ist eine Kodierung mit variabler Länge, wobei die Byte-Anzahl je nach Zeichen variiert.
- Der Datentyp
bytewird zur Darstellung von ASCII-Zeichen verwendet, während der Datentyprunefür Unicode-Zeichen genutzt wird. - Wir haben die Beziehung zwischen den Zeichentypen
byteundruneund den zugrunde liegenden Ganzzahltypen kennengelernt.
In diesem Abschnitt haben wir zunächst ASCII, UTF-8 und Unicode erläutert und anschließend gezeigt, wie Go diese Konzepte durch die Typen byte und rune praktisch umsetzt.



