Les types de caractères en Golang

GolangBeginner
Pratiquer maintenant

Introduction

Dans la section précédente, nous avons abordé les types numériques les plus courants. Dans cette partie, nous allons explorer la manière dont Go gère les caractères.

Points de connaissances :

  • Encodage ASCII
  • Encodage UTF-8
  • Jeu de caractères Unicode
  • byte
  • rune

Encodage ASCII

Aux débuts de l'informatique, le format d'encodage ASCII (American Standard Code for Information Interchange) était la norme. Il représentait les caractères sur 7 bits, permettant de coder 128 (2^7) caractères différents. Les codes allant de 0 à 31 ainsi que le 127 correspondent à des caractères de contrôle non affichables, tandis que les codes de 32 à 126 couvrent les lettres majuscules et minuscules usuelles, les chiffres et les signes de ponctuation. Vous pouvez consulter ce tableau pour plus de détails.

Avec l'évolution de l'informatique, le besoin de supporter différentes langues s'est fait sentir. L'ASCII s'est avéré insuffisant. En conséquence, diverses régions ont développé leurs propres formats, comme le GB2312 pour le chinois simplifié, l'EUC-KR pour le coréen ou le KOI8-R pour le russe.

Cependant, face à la multitude de familles linguistiques dans le monde, il est devenu indispensable de disposer d'un format d'encodage unique capable d'unifier toutes les langues. C'est ainsi qu'Unicode a été créé.

Jeu de caractères Unicode

En 1991, le Consortium Unicode a publié la première version du jeu de caractères Unicode. Son objectif était de rassembler toutes les langues au sein d'un format d'encodage universel, permettant aux ordinateurs du monde entier d'afficher et de traiter du texte plus facilement, tout en évitant les problèmes de compatibilité dans les environnements multilingues.

Toutefois, Unicode n'était à l'origine qu'un jeu de caractères ; il définissait des codes numériques pour chaque caractère, mais pas la manière dont ils devaient être stockés physiquement en mémoire. Cela a freiné son adoption massive pendant longtemps, jusqu'à l'essor d'Internet.

Encodage UTF-8

Avec le développement continu du Web, l'UTF-8, une implémentation d'Unicode, s'est imposé. Il s'agit d'un encodage à longueur variable, ce qui signifie que différents symboles peuvent occuper un nombre d'octets différent.

Par exemple, les lettres anglaises, qui se situent dans la plage ASCII, sont représentées sur 1 octet. Le caractère 'y' (valeur Unicode 121) occupe ainsi 1 octet.

Pour un usage courant, la plupart des caractères chinois occupent 3 octets. Par exemple, le caractère '实' (valeur Unicode 23454) prend 3 octets.

Cependant, certains caractères chinois plus rares nécessitent 4 octets. En effet, il existe plus de 100 000 caractères chinois, alors que 3 octets ne permettent d'en représenter qu'un peu plus de 60 000.

Un autre avantage majeur de l'UTF-8 est sa rétrocompatibilité avec l'ASCII. En réalité, l'ASCII est un sous-ensemble de l'UTF-8. Les 128 premiers caractères de l'UTF-8 correspondent exactement aux caractères ASCII. Cela signifie que les logiciels conçus initialement pour l'ASCII peuvent continuer à fonctionner avec peu ou pas de modifications. Grâce à ces atouts, l'UTF-8 est progressivement devenu le format d'encodage privilégié.

Les créateurs du langage Go, Rob Pike et Ken Thompson, sont également les inventeurs de l'UTF-8. Go possède donc une affinité particulière avec ce format. Le langage exige que les fichiers sources soient enregistrés en UTF-8. Lors de la manipulation de texte, l'UTF-8 est le choix par défaut, et la bibliothèque standard fournit de nombreuses fonctions dédiées à son encodage et son décodage.

byte et rune

Le type byte est un alias pour uint8 et occupe un octet (8 bits). Il permet de représenter tous les caractères de la table ASCII. Cependant, comme sa plage de valeurs est limitée (256 possibilités), il est insuffisant pour les caractères complexes comme les idéogrammes chinois. Pour ces derniers, nous utilisons le type rune.

Créez un nouveau fichier nommé byte.go et saisissez le code suivant :

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)
}

Après avoir exécuté le programme, vous obtiendrez le résultat suivant :

go run byte.go
Value of a: L
Value of b: L
Value of c: L

Le marqueur %c est utilisé pour afficher des caractères. On constate que les types byte et uint8 produisent le même résultat pour une valeur identique. En consultant la table ASCII, on voit que la valeur de la lettre 'L' est 76. Si nous utilisions le marqueur d'entier %d, la sortie serait également 76.

Il est donc évident qu'en Go, byte est strictement équivalent à uint8. Le même principe s'applique à rune, mais pour une plage de valeurs entières différente.

rune est un alias pour int32 et occupe quatre octets (32 bits). Il est utilisé pour représenter des caractères complexes, tels que les émojis.

Mettez à jour le fichier byte.go avec le code suivant :

package main

import "fmt"

func main() {
    var a rune = '😊' // Émoji sourire
    fmt.Printf("Value of a: %c\n", a)

    var b int32 = 9829 // Représentation décimale d'un caractère Unicode (Symbole cœur)
    fmt.Printf("Value of b: %c\n", b)
    var c rune = 0x1F496 // Représentation hexadécimale d'un caractère Unicode (Émoji cœur scintillant)
    fmt.Printf("Value of c: %c\n", c)

    var d rune = '\u0041' // Caractère Unicode représenté par son point de code (Lettre majuscule 'A')
    fmt.Printf("Value of d: %c\n", d)
    var e rune = '\U0001F609' // Caractère Unicode représenté par son point de code (Émoji clin d'œil)
    fmt.Printf("Value of e: %c\n", e)
}

Exécutez le programme pour voir le résultat :

go run byte.go

Note : Exécutez le programme dans le terminal du Bureau ou de l'IDE Web, mais évitez de l'exécuter dans l'onglet Terminal situé en haut de la VM LabEx pour un affichage correct des émojis.

Value of a: 😊
Value of b: ♥
Value of c: 💖
Value of d: A
Value of e: 😉
  • La variable a représente l'émoji sourire '😊'.
  • La variable b est initialisée avec la valeur décimale 9829, correspondant au symbole cœur '♥'.
  • La variable c utilise la valeur hexadécimale 0x1F496 pour l'émoji cœur scintillant '💖'.
  • La variable d représente la lettre 'A' via le format Unicode \u0041.
  • La variable e représente l'émoji clin d'œil '😉' via le format \U avec le point de code 0001F609.

Attention : En Go, les guillemets simples et doubles ne sont pas interchangeables. Les guillemets simples (') servent à définir des caractères uniques, tandis que les guillemets doubles (") servent à déclarer des chaînes de caractères (strings). Par conséquent, vous devez impérativement utiliser des guillemets simples pour les types byte et rune, sous peine d'erreur de compilation.

Quiz

Renforçons maintenant vos acquis. Créez un nouveau fichier nommé rune.go dans le répertoire ~/project. Complétez le code pour que le nombre hexadécimal 0x1F648 soit assigné à la variable a et que le programme affiche correctement sa valeur.

  • Exigences : Le fichier rune.go doit se trouver dans ~/project.
  • Indice : Pour les valeurs hexadécimales longues, un format spécifique doit être respecté.
package main

import "fmt"

func main() {
    var a rune = 0x1F648
    fmt.Printf("The value of a is: %c\n", a)
}

Résumé

Récapitulons ce que nous avons appris dans cette section :

  • Les caractères ASCII occupent un octet et couvrent 128 caractères.
  • L'encodage UTF-8 est une implémentation du jeu de caractères Unicode. C'est un encodage à longueur variable dont la taille en octets dépend du caractère représenté.
  • Le type de données byte est utilisé pour représenter les caractères ASCII, tandis que le type rune est utilisé pour les caractères Unicode.
  • En Go, byte est un alias de uint8 et rune est un alias de int32.

Dans ce chapitre, nous avons d'abord clarifié les concepts d'ASCII, UTF-8 et Unicode. Ensuite, nous avons mis en lumière la relation entre les types de caractères (byte, rune) et les types numériques entiers.

✨ Vérifier la solution et pratiquer