Explorer les concepts de chaînes de caractères en Rust

RustRustBeginner
Pratiquer maintenant

This tutorial is from open-source community. Access the source code

💡 Ce tutoriel est traduit par l'IA à partir de la version anglaise. Pour voir la version originale, vous pouvez cliquer ici

Introduction

Dans ce laboratoire, nous allons explorer le concept de chaînes de caractères en Rust. Rust a deux types de chaînes : String et &str.

Une String est une chaîne allouée sur le tas, pouvant grandir, qui est garantie être une séquence UTF-8 valide. D'un autre côté, &str est une tranche qui pointe vers une séquence UTF-8 valide et peut être utilisée pour examiner une String.

En Rust, les littéraux de chaîne de caractères peuvent être écrits de différentes manières, y compris en utilisant des caractères d'échappement pour représenter des caractères spéciaux. Par exemple, \x3F représente le caractère point d'interrogation et \u{211D} représente un point de code Unicode. Les littéraux de chaîne de caractères brutes peuvent également être utilisés si vous voulez écrire une chaîne telle quelle sans caractères d'échappement.

Si vous avez besoin de travailler avec des chaînes d'octets, Rust fournit des littéraux de chaîne d'octets en utilisant le préfixe b. Les chaînes d'octets peuvent avoir des caractères d'échappement d'octet, mais pas d'échappements Unicode. Les chaînes d'octets brutes peuvent également être utilisées de manière similaire aux littéraux de chaîne de caractères brutes.

Il est important de noter que str et String doivent toujours être des séquences UTF-8 valides. Si vous avez besoin de travailler avec des chaînes dans différentes encodages, vous pouvez utiliser des boîtes à outils externes comme encoding pour effectuer des conversions entre les encodages de caractères.

Note : Si le laboratoire ne spécifie pas de nom de fichier, vous pouvez utiliser n'importe quel nom de fichier que vous voulez. Par exemple, vous pouvez utiliser main.rs, le compiler et l'exécuter avec rustc main.rs &&./main.

Chaînes de caractères

Il existe deux types de chaînes de caractères en Rust : String et &str.

Une String est stockée comme un vecteur d'octets (Vec<u8>), mais est garantie toujours être une séquence UTF-8 valide. String est allouée sur le tas, peut grandir et n'est pas terminée par un caractère nul.

&str est une tranche (&[u8]) qui pointe toujours vers une séquence UTF-8 valide, et peut être utilisée pour examiner une String, tout comme &[T] est une vue dans Vec<T>.

fn main() {
    // (toutes les annotations de type sont superflues)
    // Une référence à une chaîne allouée en mémoire vive en lecture seule
    let pangram: &'static str = "the quick brown fox jumps over the lazy dog";
    println!("Pangram : {}", pangram);

    // Itérer sur les mots dans l'ordre inverse, aucune nouvelle chaîne n'est allouée
    println!("Mots dans l'ordre inverse");
    for word in pangram.split_whitespace().rev() {
        println!("> {}", word);
    }

    // Copier les caractères dans un vecteur, trier et supprimer les doublons
    let mut chars: Vec<char> = pangram.chars().collect();
    chars.sort();
    chars.dedup();

    // Créer une `String` vide et pouvant grandir
    let mut string = String::new();
    for c in chars {
        // Insérer un caractère à la fin de la chaîne
        string.push(c);
        // Insérer une chaîne à la fin de la chaîne
        string.push_str(", ");
    }

    // La chaîne tronquée est une tranche de la chaîne d'origine, donc aucune nouvelle
    // allocation n'est effectuée
    let chars_to_trim: &[char] = &[' ', ','];
    let trimmed_str: &str = string.trim_matches(chars_to_trim);
    println!("Caractères utilisés : {}", trimmed_str);

    // Allouer une chaîne sur le tas
    let alice = String::from("I like dogs");
    // Allouer de nouvelles ressources mémoire et stocker la chaîne modifiée là
    let bob: String = alice.replace("dog", "cat");

    println!("Alice dit : {}", alice);
    println!("Bob dit : {}", bob);
}

Plus de méthodes str/String peuvent être trouvées dans les modules std::str et std::string.

Littéraux et caractères d'échappement

Il existe plusieurs manières d'écrire des littéraux de chaîne de caractères avec des caractères spéciaux. Tous donnent un &str similaire, il est donc préférable d'utiliser la forme la plus pratique à écrire. De même, il existe plusieurs manières d'écrire des littéraux de chaîne d'octets, qui donnent tous &[u8; N].

Généralement, les caractères spéciaux sont escapés avec un caractère antislash : \. Ainsi, vous pouvez ajouter n'importe quel caractère à votre chaîne, même des caractères non imprimables et ceux que vous ne savez pas comment taper. Si vous voulez un antislash littéral, échappez-le avec un autre : \\

Les délimiteurs de littéraux de chaîne ou de caractères apparaissant dans un littéral doivent être escapés : "\"", '\''.

fn main() {
    // Vous pouvez utiliser des caractères d'échappement pour écrire des octets par leurs valeurs hexadécimales...
    let byte_escape = "I'm writing \x52\x75\x73\x74!";
    println!("Que faites-vous\x3F (\\x3F signifie?) {}", byte_escape);

    //... ou des points de code Unicode.
    let unicode_codepoint = "\u{211D}";
    let character_name = "\"DOUBLE-STRUCK CAPITAL R\"";

    println!("Le caractère Unicode {} (U+211D) s'appelle {}",
                unicode_codepoint, character_name );


    let long_string = "String literals
                        can span multiple lines.
                        The linebreak and indentation here ->\
                        <- can be escaped too!";
    println!("{}", long_string);
}

Parfois, il y a trop de caractères à échapper ou il est simplement beaucoup plus pratique d'écrire une chaîne telle quelle. C'est là que les littéraux de chaîne brutes entrent en jeu.

fn main() {
    let raw_str = r"Escapes don't work here: \x3F \u{211D}";
    println!("{}", raw_str);

    // Si vous avez besoin de guillemets dans une chaîne brute, ajoutez une paire de #
    let quotes = r#"And then I said: "There is no escape!""#;
    println!("{}", quotes);

    // Si vous avez besoin de "## dans votre chaîne, utilisez simplement plus de ## dans le délimiteur.
    // Vous pouvez utiliser jusqu'à 65535 #.
    let longer_delimiter = r###"A string with "## in it. And even "##!"###;
    println!("{}", longer_delimiter);
}

Voulez-vous une chaîne qui n'est pas UTF-8? (Rappelez-vous, str et String doivent être des séquences UTF-8 valides). Ou peut-être que vous voulez un tableau d'octets qui est surtout du texte? Les chaînes d'octets viennent en aide!

use std::str;

fn main() {
    // Notez que ce n'est pas réellement un `&str`
    let bytestring: &[u8; 21] = b"this is a byte string";

    // Les tableaux d'octets n'ont pas le trait `Display`, donc les imprimer est un peu limité
    println!("Une chaîne d'octets : {:?}", bytestring);

    // Les chaînes d'octets peuvent avoir des caractères d'échappement d'octet...
    let escaped = b"\x52\x75\x73\x74 as bytes";
    //... mais pas d'échappements Unicode
    // let escaped = b"\u{211D} is not allowed";
    println!("Certains octets escapés : {:?}", escaped);


    // Les chaînes d'octets brutes fonctionnent comme les chaînes brutes
    let raw_bytestring = br"\u{211D} is not escaped here";
    println!("{:?}", raw_bytestring);

    // Convertir un tableau d'octets en `str` peut échouer
    if let Ok(my_str) = str::from_utf8(raw_bytestring) {
        println!("Et le même en tant que texte : '{}'", my_str);
    }

    let _quotes = br#"You can also use "fancier" formatting, \
                    like with normal raw strings"#;

    // Les chaînes d'octets ne doivent pas être UTF-8
    let shift_jis = b"\x82\xe6\x82\xa8\x82\xb1\x82\xbb"; // "ようこそ" en SHIFT-JIS

    // Mais alors elles ne peuvent pas toujours être converties en `str`
    match str::from_utf8(shift_jis) {
        Ok(my_str) => println!("Conversion réussie : '{}'", my_str),
        Err(e) => println!("Conversion échouée : {:?}", e),
    };
}

Pour les conversions entre les encodages de caractères, consultez la boîte à outils encoding.

Une liste plus détaillée des manières d'écrire des littéraux de chaîne de caractères et des caractères d'échappement est donnée dans le chapitre 'Tokens' de la Rust Reference.

Sommaire

Félicitations! Vous avez terminé le laboratoire sur les chaînes de caractères. Vous pouvez pratiquer d'autres laboratoires sur LabEx pour améliorer vos compétences.