Alias et chaînes de caractères

Maintenant que nous savons ce que sont les tableaux, que nous avons jeté un coup d'œil au mot-clé immutable et aux types fondamentaux, il est temps d'introduire deux nouvelles constructions en une ligne :

alias string = immutable(char)[];

Le terme string est défini par une instruction alias qui le définit comme une tranche de immutable(char)s. Cela signifie que, une fois qu'une string a été construite, son contenu ne changera plus. Et c'est d'ailleurs la deuxième nouveauté : bienvenue à UTF-8 string!

Étant immutables, les strings peuvent parfaitement être partagées entre différents threads. Une string est une tranche, qu'on peut retrancher sans réallouer de mémoire. La fonction de la bibliothèque standard std.algorithm.splitter par exemple, peut séparer une chaîne de caractères en différentes parties séparées par un retour à ligne sans allouer de mémoire.

En plus de la chaîne de caractères UTF-8 string, il y a deux autres types :

alias wstring = immutable(wchar)[]; // UTF-16
alias dstring = immutable(dchar)[]; // UTF-32

Les variantes sont facilement convertibles de l'une à l'autre en utilisant la fonction to de std.conv:

dstring maDstring = to!dstring(maString);
string maString = to!string(maString);

Chaînes de caractères unicode

Cela signifie qu'une string est définie comme un tableau de codets unicode 8-bits. Toutes les opérations sur les tableaux peuvent être utilisées sur les chaînes de caractères, mais elles travailleront au niveau des codets et pas au niveau des caractères. De la même façon, les algorithmes de la bibliothèque standard traiteront les strings comme des séquences de points de code, ou éventuellement comme une séquence de graphèmes si on utilise std.uni.byGrapheme.

Ce petit example illustre ces différences :

string s = "\u0041\u0308"; // Ä

writeln(s.length); // 3

import std.range : walkLength;
writeln(s.walkLength); // 2

import std.uni : byGrapheme;
writeln(s.byGrapheme.walkLength); // 1

Ici, la longueur du tableau s est 3, parce qu'il contient 3 codets : 0x41, 0x03 et 0x08. Ces deux derniers définissent un seul point de code et walkLength (fonction de la bibliothèque standard qui permet de calculer la longueur d'une range quelconque) compte deux points de code au total. Finalement, byGrapheme réalise des calculs plutôt couteux pour déterminer que ces deux points de code forme un seul caractère affiché.

Traiter correctement Unicode peut être très compliqué, mais la plupart du temps, les développeurs D considèrent les variables string comme des tableaux magiques et se basent sur la bibliothèque standard. Si l'on veut itérer sur les codets d'une string, on peut utiliser la fonction byCodeUnit.

L'auto-décodage en D est expliqué plus en détail dans le chapitre dédié à l'unicode, plus loin dans ce tutoriel.

strings multi-lignes

Pour créer une string multi-ligne, on peut utiliser la syntaxe string chaine = q{...}:

string multiligne = q{ Ceci
    pourrait être un
    long document
};

strings brutes

Il est également possible d'utiliser les strings brutes pour éviter le laborieux travail d'échappement des caractères spéciaux. Les strings brutes peuvent être déclarées soit avec des backticks ( ` ... ` ) ou avec avec le préfixe "r" (r"...").

string brute = `"string" brute`; // "string" brute
string brute2 = r"`string` brute"; // `string` brute

Aller plus loin

rdmd playground.d