Blog ENI : Toute la veille numérique !
Accès illimité 24h/24 à tous nos livres & vidéos ! 
Découvrez la Bibliothèque Numérique ENI. Cliquez ici
💥 1 livre papier acheté 
= la version en ligne automatiquement offerte. Cliquez ici
  1. Livres et vidéos
  2. Rust
  3. Les chaînes de caractères en Rust
Extrait - Rust Développez des programmes robustes et sécurisés
Extraits du livre
Rust Développez des programmes robustes et sécurisés
5 avis
Revenir à la page d'achat du livre

Les chaînes de caractères en Rust

Introduction

Nous avons déjà entraperçu et manipulé à plusieurs reprises des chaînes de caractères en langage Rust, notamment avec String et str. L’implantation en mémoire a également été abordée, mais nous y reviendrons ici.

Nous en profiterons pour expliquer le rôle de char et son utilisation en Rust. Nous verrons surtout les différentes manières d’utiliser et de manipuler des caractères en langage Rust.

Commençons par évoquer les questions d’encodage, Unicode et UTF-8, qui sont la base des caractères en Rust (char) et des chaînes de caractères (String, str).

Encodages Unicode et UTF-8 et caractères en Rust

1. Quelques définitions

Unicode est un standard logiciel qui permet d’encoder n’importe quel caractère issu de toutes les langues du monde.

UTF-8 (Universal Character Set Transformation Format - 8 bits) est un codage de caractères conçu pour encoder l’ensemble des caractères du répertoire universel. UTF-8 est totalement compatible avec le standard Unicode.

2. Encodage en Rust

a. Le type char et l’Unicode

Le caractère seul (char) correspond en langage Rust à une valeur numérique Unicode (ce que l’on nomme dans le jargon un « point de code »).

Concrètement, un char en Rust se code sur 32 bits (4 octets).

b. Les types String et str et l’UTF-8

String et str partagent le fait de correspondre à un encodage UTF-8.

Le type str est véritablement le type primitif de chaînes de caractères en Rust. On dit que ce type est toujours valide au sens de UTF-8.

On a déjà rencontré ce type dans ce livre, en particulier sous les deux écritures suivantes correspondant à un emprunt :

&str 
 
&'static str 

Le type String correspond à une chaîne extensible encodée en UTF-8. Pourquoi extensible ? Car elle n’est ni plus ni moins qu’un vecteur de caractères encodés sur un entier...

À la découverte des caractères (char) en Rust

1. Nature des caractères

Commençons par créer un projet support pour la présente section et pour la suivante consacrée à String et str :

cargo new projet_car_chaine --bin 
     Created binary (application) `projet_car_chaine` package 

Rust fournit plusieurs méthodes visant à connaître la nature d’un caractère. Ces méthodes permettent ainsi de préciser si le caractère est numérique (is_numeric), alphabétique (is_alphabetic), alphanumérique (is_alphanumeric), ou encore s’il est un caractère espace (is_whitespace) ou un caractère dit « de contrôle » (is_control).

On crée donc des variables stockant des caractères, c’est-à-dire quelque chose stocké sur 32 bits, par défaut sur la pile :

fn main() { 
 
    // Des caractères. 
    let quatre = '4'; 
    println!("'4' est numérique ? : {}", quatre.is_numeric()); 
 
    let a = 'a'; 
    println!("'a' est alphabétique ? : {}", a.is_alphabetic()); 
 
    let etoile...

À la découverte de String et str

1. Introduction

Rappelons que ces deux types chaînes de caractères n’incluent que des valeurs UTF-8 bien formées, c’est-à-dire que le compilateur Rust garantit cela. Toutes les opérations conduites sur des types chaînes de caractères (String ou str) sont garanties et maintiennent un contenu bien formé au sens de UTF-8.

2. Le type str

Le type str ou plutôt &str correspond à une séquence d’octets en UTF-8 qui est non mutable. Par ailleurs, la taille de la chaîne de caractères n’est pas connue (contrairement à String). C’est ce que l’on appelle une tranche (slice) de chaîne de caractères.

La documentation en ligne de ce type est disponible à cette adresse : https://doc.rust-lang.org/std/str/index.html

On peut définir ce type de façon implicite, mais on peut également le préciser de manière explicite en indiquant &’static str.

fn fonction_str() { 
    let valeur_str = "bonjour"; 
    println!("valeur_str : {}", valeur_str); 
 
    let valeur_str_2 : &'static str = "BONJOUR"; 
    println!("valeur_str_2 : {}", valeur_str_2); 
} 

En sortie, on obtient ceci :

valeur_str : bonjour 
valeur_str_2 : BONJOUR 

Le type &str n’est pas de taille fixe, ni en réalité de taille connue. Il ne peut donc implémenter le trait Clone. Si l’on veut copier une valeur de ce type, il faut recourir à un autre trait : ToOwned. Ainsi, on peut utiliser la méthode to_owned, qui renvoie une copie de la chaîne de caractères :

let valeur_str_3 = valeur_str_2.to_owned(); 
println!("valeur_str_3 : {}", valeur_str_3); 

On peut également étudier une chaîne de caractères de type &str en ayant recours aux tranches. On accède à la valeur de diverses tranches. On peut vérifier également la longueur d’une tranche et inspecter son contenu :

println!("&valeur_str_3[..3] : {}", &valeur_str_3[..3]); 
println!("&valeur_str_3[3..] : {}", &valeur_str_3[3..]); ...

Un mot sur les expressions régulières

On désigne par « expression régulière » un outil qui permet, dans la plupart des langages de programmation évolués, de requêter des chaînes de caractères selon un motif ou une séquence définie. Il existe une similarité avec le filtrage par motif.

Néanmoins, Rust fournit aussi une caisse dédiée aux expressions régulières car elles s’avèrent plus efficaces et performantes dans certains cas précis.

La caisse qui contient le nécessaire s’appelle regex. On doit donc référencer ainsi cette caisse pour l’utiliser :

extern crate regex 

La documentation de cette caisse est disponible à cette adresse : https://docs.rs/regex/latest/regex/

La documentation sur crates.io est quant à elle accessible ici : https://crates.io/crates/regex

Prenons un petit exemple. On reçoit des dates au format suivant : YYYY-MM-JJ. On souhaite extraire respectivement l’année, le mois et le jour de ce format. Nous allons utiliser les expressions régulières en Rust.

On commence par ajouter une dépendance dans le fichier cargo.toml :

[dependencies] 
regex = "1.5" 

Puis on peut commencer à établir notre code. On référence la caisse et le module dont on aura...