Le type rune en Go est un alias de int32.
Étant donné ce type int32 sous-jacent, le type rune contient une valeur entière signée de 32 bits.
Cependant, contrairement à un type int32, la valeur entière stockée dans un type rune représente un seul caractère Unicode.
Unicode est un sur-ensemble d'ASCII qui représente les caractères en associant un nombre unique à chaque caractère. Ce nombre unique s'appelle un point de code Unicode. Unicode vise à représenter tous les caractères du monde, qu'il s'agisse des différents alphabets, des nombres, des symboles ou même des emoji, sous forme de points de code Unicode.
En Go, le type rune représente un seul point de code Unicode.
Le tableau suivant contient des exemples de caractères Unicode accompagnés de leur point de code Unicode et de leur valeur décimale :
| Unicode Character | Unicode Code Point | Decimal Value |
|---|---|---|
| 0 | U+0030 |
48 |
| A | U+0041 |
65 |
| a | U+0061 |
97 |
| ¿ | U+00BF |
191 |
| π | U+03C0 |
960 |
| 🧠 | U+1F9E0 |
129504 |
UTF-8 est un encodage de caractères à largeur variable, utilisé pour encoder chaque point de code Unicode sur 1, 2, 3 ou 4 octets.
Comme un point de code Unicode peut être encodé sur 4 octets au maximum, le type rune doit pouvoir contenir jusqu'à 4 octets de données.
C'est pourquoi le type rune est un alias de int32 : un type int32 est capable de contenir jusqu'à 4 octets de données.
Les fichiers de code source Go sont encodés en UTF-8.
Les variables de type rune se déclarent en plaçant un caractère entre apostrophes :
myRune := '¿'
Comme rune n'est qu'un alias de int32, afficher le type d'une rune donne int32 :
myRune := '¿'
fmt.Printf("myRune type: %T\n", myRune)
// Output: myRune type: int32
De même, afficher la valeur d'une rune donne sa valeur entière (décimale) :
myRune := '¿'
fmt.Printf("myRune value: %v\n", myRune)
// Output: myRune value: 191
Pour afficher le caractère Unicode représenté par la rune, utilise le verbe de formatage %c :
myRune := '¿'
fmt.Printf("myRune Unicode character: %c\n", myRune)
// Output: myRune Unicode character: ¿
Pour afficher le point de code Unicode représenté par la rune, utilise le verbe de formatage %U :
myRune := '¿'
fmt.Printf("myRune Unicode code point: %U\n", myRune)
// Output: myRune Unicode code point: U+00BF
Outre le fait de définir une rune en entourant le caractère d'apostrophes, tu peux aussi préciser le nombre en hexadécimal ou en décimal :
myRune := rune(0xbf)
myRune = 191
fmt.Printf("myRune Unicode character: %c\n", myRune)
// Output: myRune Unicode character: ¿
Les strings en Go sont encodées en UTF-8, ce qui signifie qu'elles contiennent des caractères Unicode. Les caractères dans les strings sont stockés et encodés sur 1, 2, 3 ou 4 octets selon le caractère Unicode qu'ils représentent.
En Go, on utilise des slices pour représenter des séquences, et on peut parcourir ces slices avec range.
Quand on parcourt une string, Go la convertit en une série de runes, chacune occupant 4 octets (pour rappel, le type rune est un alias d'int32 !)
Même si une string n'est qu'un slice d'octets, le mot-clé range parcourt les runes d'une string, et non ses octets.
Dans cet exemple, la variable index représente l'indice de départ de la séquence d'octets de la rune courante, et la variable char représente la rune courante :
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
Comme les runes peuvent être stockées sur 1, 2, 3 ou 4 octets, la longueur d'une string n'est pas toujours égale au nombre de caractères qu'elle contient.
Utilise la fonction intégrée len pour obtenir la longueur d'une string en octets, et la fonction utf8.RuneCountInString pour obtenir le nombre de runes d'une string :
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
On peut convertir un slice de runes en string :
myRuneSlice := []rune{'e', 'x', 'e', 'r', 'c', 'i', 's', 'm'}
myString := string(myRuneSlice)
fmt.Println(myString)
// Output: exercism
De même, on peut convertir une string en slice de runes. Pour rappel, sans verbe de formatage, afficher une rune donne sa valeur entière (décimale) :
myString := "exercism"
myRuneSlice := []rune(myString)
fmt.Println(myRuneSlice)
// Output: [101 120 101 114 99 105 115 109]