Der Typ rune in Go ist ein Alias für int32.
Aufgrund dieses zugrunde liegenden Typs int32 speichert der Typ rune einen vorzeichenbehafteten 32-Bit-Ganzzahlwert.
Anders als ein int32-Typ stellt der im Typ rune gespeicherte Ganzzahlwert jedoch ein einzelnes Unicode-Zeichen dar.
Unicode ist eine Obermenge von ASCII, die Zeichen darstellt, indem sie jedem Zeichen eine eindeutige Zahl zuweist. Diese eindeutige Zahl heißt Unicode-Codepunkt. Unicode hat zum Ziel, alle Zeichen der Welt, darunter verschiedene Alphabete, Zahlen, Symbole und sogar Emojis, als Unicode-Codepunkte darzustellen.
In Go stellt der Typ rune einen einzelnen Unicode-Codepunkt dar.
Die folgende Tabelle enthält Beispiele für Unicode-Zeichen zusammen mit ihrem Unicode-Codepunkt und ihrem Dezimalwert:
| Unicode-Zeichen | Unicode-Codepunkt | Dezimalwert |
|---|---|---|
| 0 | U+0030 |
48 |
| A | U+0041 |
65 |
| a | U+0061 |
97 |
| ¿ | U+00BF |
191 |
| π | U+03C0 |
960 |
| 🧠 | U+1F9E0 |
129504 |
UTF-8 ist eine Zeichenkodierung mit variabler Breite, die jeden Unicode-Codepunkt als 1, 2, 3 oder 4 Bytes kodiert.
Da ein Unicode-Codepunkt als höchstens 4 Bytes kodiert werden kann, muss der Typ rune in der Lage sein, bis zu 4 Bytes an Daten zu speichern.
Deshalb ist der Typ rune ein Alias für int32, denn ein int32-Typ kann bis zu 4 Bytes an Daten speichern.
Go-Quellcodedateien werden mit UTF-8 kodiert.
Variablen vom Typ rune deklarierst du, indem du ein Zeichen in einfache Anführungszeichen setzt:
myRune := '¿'
Da rune nur ein Alias für int32 ist, ergibt die Ausgabe des Typs einer Rune int32:
myRune := '¿'
fmt.Printf("myRune type: %T\n", myRune)
// Output: myRune type: int32
Ebenso ergibt die Ausgabe des Werts einer Rune ihren Ganzzahlwert (Dezimalwert):
myRune := '¿'
fmt.Printf("myRune value: %v\n", myRune)
// Output: myRune value: 191
Um das durch die Rune dargestellte Unicode-Zeichen auszugeben, verwendest du das Formatierungsverb %c:
myRune := '¿'
fmt.Printf("myRune Unicode character: %c\n", myRune)
// Output: myRune Unicode character: ¿
Um den durch die Rune dargestellten Unicode-Codepunkt auszugeben, verwendest du das Formatierungsverb %U:
myRune := '¿'
fmt.Printf("myRune Unicode code point: %U\n", myRune)
// Output: myRune Unicode code point: U+00BF
Strings in Go werden mit UTF-8 kodiert, das heißt, sie enthalten Unicode-Zeichen. Zeichen in Strings werden als 1, 2, 3 oder 4 Bytes gespeichert und kodiert, je nachdem, welches Unicode-Zeichen sie darstellen.
In Go werden Slices verwendet, um Sequenzen darzustellen, und diese Slices lassen sich mit range durchlaufen.
Wenn wir über einen String iterieren, wandelt Go den String in eine Folge von Runen um, von denen jede 4 Bytes groß ist (denk daran: Der Typ rune ist ein Alias für ein int32!)
Auch wenn ein String nur ein Slice von Bytes ist, iteriert das Schlüsselwort range über die Runen eines Strings, nicht über seine Bytes.
In diesem Beispiel stellt die Variable index den Startindex der Bytefolge der aktuellen Rune dar und die Variable char die aktuelle Rune:
myString := "❗hello"
for index, char := range myString {
fmt.Printf("Index: %d\tCharacter: %c\t\tCode Point: %U\n", index, char, char)
}
// Output:
// Index: 0 Character: ❗ Code Point: U+2757
// Index: 3 Character: h Code Point: U+0068
// Index: 4 Character: e Code Point: U+0065
// Index: 5 Character: l Code Point: U+006C
// Index: 6 Character: l Code Point: U+006C
// Index: 7 Character: o Code Point: U+006F
Da Runen als 1, 2, 3 oder 4 Bytes gespeichert werden können, entspricht die Länge eines Strings nicht immer der Anzahl der Zeichen im String.
Verwende die eingebaute Funktion len, um die Länge eines Strings in Bytes zu ermitteln, und die Funktion utf8.RuneCountInString, um die Anzahl der Runen in einem String zu ermitteln:
import "unicode/utf8"
myString := "❗hello"
stringLength := len(myString)
numberOfRunes := utf8.RuneCountInString(myString)
fmt.Printf("myString - Length: %d - Runes: %d\n", stringLength, numberOfRunes)
// Output: myString - Length: 8 - Runes: 6
Du hast die Aufgabe, eine Log-Bibliothek zu erstellen, die beim Verwalten der Logs deiner Organisation hilft. Mit dieser Bibliothek können Nutzer herausfinden, welche Anwendung ein bestimmtes Log ausgegeben hat, beschädigte Logs reparieren und feststellen, ob eine Logzeile ein bestimmtes Zeichenlimit einhält.
Logs stammen aus verschiedenen Anwendungen, die jeweils ihr eigenes proprietäres Logformat verwenden. Bevor ein Log in einem Log-Aggregationssystem gespeichert werden kann, muss die Anwendung ermittelt werden, die es ausgegeben hat.
Implementiere die Funktion Application, die eine Logzeile entgegennimmt und die Anwendung zurückgibt, die diese Logzeile ausgegeben hat.
Um zu ermitteln, welche Anwendung eine bestimmte Logzeile ausgegeben hat, suche in der Logzeile nach einem bestimmten Zeichen, wie in der folgenden Tabelle angegeben:
| Anwendung | Zeichen | Unicode-Codepoint |
|---|---|---|
recommendation |
❗ | U+2757 |
search |
🔍 | U+1F50D |
weather |
☀ | U+2600 |
Wenn eine Logzeile keines der Zeichen aus der obigen Tabelle enthält, gib default an den Aufrufer zurück.
Wenn eine Logzeile mehr als eines der Zeichen aus der obigen Tabelle enthält, gib die Anwendung zurück, die zum ersten von links nach rechts gefundenen Zeichen in der Logzeile gehört.
Application("❗ recommended search product 🔍")
// => recommendation
Aufgrund eines seltenen, aber hartnäckigen Bugs in der Log-Infrastruktur können bestimmte Zeichen in Logs beschädigt werden. Nachdem du einige Zeit damit verbracht hast, die beschädigten Zeichen und ihren ursprünglichen Wert zu identifizieren, beschließt du, die Log-Bibliothek zu erweitern, damit sie beim Reparieren beschädigter Logs hilft.
Implementiere die Funktion Replace, die eine Logzeile, ein beschädigtes Zeichen und den ursprünglichen Wert entgegennimmt und eine geänderte Logzeile zurückgibt, in der alle Vorkommen des beschädigten Zeichens durch den ursprünglichen Wert ersetzt wurden.
log := "please replace '👎' with '👍'"
Replace(log, '👎', '👍')
// => please replace '👍' with '👍'"
Systeme, die für die Anzeige von Logs zuständig sind, haben eine Obergrenze für die Anzahl der Zeichen, die pro Logzeile angezeigt werden können. Deshalb bitten Nutzer darum, dass diese Bibliothek eine Hilfsfunktion enthält, mit der sich feststellen lässt, ob eine Logzeile ein bestimmtes Zeichenlimit einhält.
Implementiere die Funktion WithinLimit, die eine Logzeile und ein Zeichenlimit entgegennimmt und zurückgibt, ob die Logzeile das Zeichenlimit einhält.
WithinLimit("hello❗", 6)
// => true
Melde dich bei Exercism an, um Go mit 34 Konzepte165 Übungen und echtem menschlichen Mentoring zu lernen und zu meistern, alles kostenlos.