Les chaînes de caractères en Rust
La gestion du texte est l’un des premiers endroits où Rust paraît différent des autres langages, surtout parce qu’il possède deux types de chaînes de caractères. Une fois que vous savez pourquoi, tout devient beaucoup plus clair.
&str ou String
Section intitulée « &str ou String »&str(« string slice », une tranche de chaîne) : du texte qui existe déjà quelque part, souvent écrit directement dans votre code. Sa taille est fixe, il ne peut pas grandir.String: un texte qui vous appartient et qui peut grandir. Vous pouvez y ajouter du contenu, et il est stocké sur le tas (heap).
fn main() { let literal: &str = "bonjour"; // une string slice let owned: String = String::from("bonjour"); // une String possédée
println!("{literal} / {owned}");}Une règle simple : si vous affichez seulement un texte fixe, "comme ceci" (un &str) suffit. Si vous devez construire, agrandir ou modifier du texte pendant l’exécution, utilisez String.
Agrandir une String
Section intitulée « Agrandir une String »fn main() { let mut greeting = String::from("Bonjour"); greeting.push_str(", le monde "); // ajoute un &str greeting.push('!'); // ajoute un seul caractère
println!("{greeting}");}Sortie :
Bonjour, le monde !Combiner des chaînes
Section intitulée « Combiner des chaînes »Vous pouvez assembler des chaînes avec +, ou utiliser format! (souvent l’option la plus lisible) :
fn main() { let first = String::from("Bonjour, "); let second = String::from("le monde !");
let combined = first + &second; // remarquez le & devant second println!("{combined}");
// format! est souvent plus facile à lire : let name = "Ferris"; let greeting = format!("Bonjour, {name} !"); println!("{greeting}");}Méthodes utiles sur les chaînes
Section intitulée « Méthodes utiles sur les chaînes »Quelques méthodes que vous utiliserez tout le temps :
fn main() { let text = " Hello, Rust! ";
println!("{}", text.trim()); // "Hello, Rust!" (sans espaces autour) println!("{}", text.to_uppercase()); // " HELLO, RUST! " println!("{}", text.to_lowercase()); // " hello, rust! " println!("{}", text.contains("Rust")); // true println!("{}", text.trim().len()); // 12 (longueur en octets) println!("{}", text.trim().replace("Rust", "World")); // "Hello, World!"}Le texte de cet exemple reste en anglais exprès : .len() compte des octets, et une lettre accentuée comme « é » en occupe deux. Avec du texte français, le nombre affiché ne correspondrait plus au nombre de lettres.
Parcourir une chaîne
Section intitulée « Parcourir une chaîne »Pour avancer caractère par caractère, utilisez .chars() :
fn main() { for c in "abc".chars() { println!("{c}"); }}Exercices
Section intitulée « Exercices »1. Nettoyer une saisie désordonnée
Section intitulée « 1. Nettoyer une saisie désordonnée »Quelqu’un a tapé " rUsT is FUN " dans un formulaire. Transformez-le en rust is great : retirez les espaces en trop, passez tout en minuscules et remplacez fun par great. Affichez ensuite le résultat et sa longueur. Indice : les méthodes de chaîne peuvent s’enchaîner les unes après les autres : text.trim().to_lowercase()....
Voir la solution
fn main() { let input = " rUsT is FUN ";
// d'abord trim, puis minuscules, puis on remplace "fun" (désormais en minuscules) let clean = input.trim().to_lowercase().replace("fun", "great");
println!("{clean}"); println!("{} octets", clean.len());}Sortie :
rust is great13 octetsL’ordre compte : si vous appeliez .replace("fun", "great") avant .to_lowercase(), rien ne serait remplacé, car le texte contiendrait encore FUN. (Le texte reste en anglais pour que la longueur affichée corresponde au nombre de lettres.)
2. Construire une adresse e-mail
Section intitulée « 2. Construire une adresse e-mail »À partir de first = "Ada" et last = "Lovelace", construisez la String [email protected] et affichez-la. Affichez ensuite si elle contient un @. Indice : format! accepte des expressions comme first.to_lowercase() comme arguments pour ses emplacements {}.
Voir la solution
fn main() { let first = "Ada"; let last = "Lovelace";
let email = format!("{}.{}@example.com", first.to_lowercase(), last.to_lowercase());
println!("{email}"); println!("semble valide : {}", email.contains('@'));}Sortie :
semble valide : trueRécapitulatif
Section intitulée « Récapitulatif »&strest un texte emprunté et fixe ;Stringvous appartient et peut grandir.- On agrandit une
Stringavec.push_str()(pour du texte) ou.push()(pour un seul caractère). - Préférez
format!à+pour combiner des chaînes : c’est plus clair et rien n’est déplacé. - Méthodes courantes :
.trim(),.to_uppercase(),.contains(),.replace(),.chars().
Petit quiz
Section intitulée « Petit quiz »Petit quiz
1. Quel type de chaîne vous appartient et peut grandir pendant l'exécution ?
2. Pourquoi cette page préfère-t-elle format! à + pour combiner plus d'une ou deux chaînes ?
3. Pourquoi ne peut-on pas indexer une chaîne Rust avec text[0] ?
4. Quelle méthode ajoute un seul caractère à une String, comme greeting.push('!') ?
Score : 0 / 4
Pour aller plus loin
Section intitulée « Pour aller plus loin »- Storing UTF-8 Encoded Text with Strings — The Rust Book (en anglais) : le chapitre officiel sur
String, y compris pourquoi on ne peut pas indexer par position. - String Slices — The Rust Book (en anglais) : ce qu’est vraiment un
&str, une fois que vous connaissez le borrowing (emprunt). - Strings — Rust by Example (en anglais) : des exemples exécutables de
Stringet&str, plus les caractères d’échappement et les chaînes brutes. String— documentation de la bibliothèque standard (en anglais) : toutes les méthodes d’uneStringpossédée, chacune avec un petit exemple.str— documentation de la bibliothèque standard (en anglais) : des méthodes commetrim,contains,replaceetsplit, utilisables sur n’importe quel texte.