Aller au contenu

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 (« 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}");
}
▶ Essayez par vous-même

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.

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 !
▶ Essayez par vous-même

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}");
}
▶ Essayez par vous-même

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!"
}
▶ Essayez par vous-même

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.

Pour avancer caractère par caractère, utilisez .chars() :

fn main() {
for c in "abc".chars() {
println!("{c}");
}
}
▶ Essayez par vous-même

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 great
13 octets
▶ Essayez par vous-même

L’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.)

À 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 : true
▶ Essayez par vous-même
  • &str est un texte emprunté et fixe ; String vous appartient et peut grandir.
  • On agrandit une String avec .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

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