Phase 2Ownership & emprunt

#7 Slices

&str, &[T], tranches

Qu'est-ce qu'une slice ?

Une slice est une référence vers une portion contiguë d'une collection. Elle ne possède pas les données — elle les emprunte. Les slices permettent de travailler avec une partie d'un tableau ou d'une chaîne sans copier les données.

En interne, une slice contient deux informations : un pointeur vers le début des données et une longueur.

Slices de chaînes (&str)

Le type &str est une slice de chaîne de caractères. C'est le type le plus courant pour manipuler du texte en Rust.

Slice de String
let s = String::from("bonjour le monde");

let bonjour = &s[0..7];   // "bonjour"
let monde = &s[11..16];   // "monde"

println!("Premier mot : {bonjour}");

La syntaxe [début..fin] crée une slice du caractère à l'index début jusqu'à (mais sans inclure) fin. On peut omettre le début ou la fin :

Syntaxe abrégée
let s = String::from("bonjour");

let s1 = &s[0..4]; // "bonj"
let s2 = &s[..4];  // Même chose

let s3 = &s[4..7];   // "our"
let s4 = &s[4..];    // Même chose

let s5 = &s[0..7];   // "bonjour"
let s6 = &s[..];     // Même chose (la chaîne entière)

Les littéraux de chaînes ("bonjour") sont déjà des &str. C'est une slice pointant vers les données stockées dans le binaire du programme.

Slices de tableaux (&[T])

Les slices fonctionnent aussi avec les tableaux et les vecteurs. Le type est &[T]T est le type des éléments.

Slice de tableau
let nombres = [1, 2, 3, 4, 5];

let milieu = &nombres[1..4]; // [2, 3, 4]
println!("Slice : {milieu:?}");

// Fonctionne aussi avec les Vec
let v = vec![10, 20, 30, 40, 50];
let debut = &v[..3]; // [10, 20, 30]

Notez l'utilisation de :? dans println! pour afficher un tableau en mode debug.

Slices en paramètre

Les slices sont très utiles comme paramètres de fonctions. Au lieu d'exiger un String ou un Vec, préférez accepter une slice pour plus de flexibilité :

Fonction avec slice
fn premier_mot(s: &str) -> &str {
    let octets = s.as_bytes();

    for (i, &octet) in octets.iter().enumerate() {
        if octet == b' ' {
            return &s[..i];
        }
    }

    s // Pas d'espace → tout le texte est un mot
}

fn main() {
    let phrase = String::from("Rust est génial");
    let mot = premier_mot(&phrase); // &String → &str automatiquement
    println!("Le premier mot est : {mot}");

    // Fonctionne aussi avec un &str directement
    let mot2 = premier_mot("Hello world");
}

Accepter &str plutôt que &String rend la fonction plus générique : elle accepte à la fois des String (via la coercition automatique) et des littéraux de chaînes.

À vous de jouer

Essayez les commandes ci-dessous pour manipuler des slices :

terminal — cargo
user@stemlegacy:~/slices-demo$