Comment obtenir une tranche comme tableau en Rust : du débutant au gourou

Formateur Python en ligne pour débutants

Apprenez Python facilement sans surcharge théorique. Résolvez des tâches pratiques avec vérification automatique et écrivez du code directement dans le navigateur.

Start Course

Tranche comme tableau en Rust : pourquoi c'est difficile et comment le faire correctement

\n\n

Quiconque a écrit en Rust plus de quelques jours a rencontré une situation frustrante : vous avez un &[u8] (tranche), mais la fonction a besoin d'un [u8; 4] (tableau). En C, vous prendriez simplement un pointeur. En Python, vous feriez une découpe. En Rust... commence la danse du scalp. Mais n'ayez pas peur — derrière cette complexité se cache une sécurité géniale.

\n\n

Dans cet article, nous allons voir comment obtenir une tranche comme tableau en Rust de toutes les manières possibles : du « rapide et sale » au « correct et fiable ». Vous apprendrez pourquoi Rust ne permet pas simplement de transformer une tranche en tableau, et comment contourner ce « problème » avec une performance maximale.

\n\n

Pourquoi Rust ne permet-il pas simplement de copier une tranche dans un tableau ?

\n\n

Imaginez : vous commandez une pizza, et on vous apporte une part. Vous dites : « C'est une partie de la pizza, faites-en une entière ». Il en va de même pour la tranche — c'est une référence à une partie des données, tandis que le tableau est un type propriétaire de longueur fixe. La taille du tableau est connue à la compilation, tandis que la taille de la tranche ne l'est qu'à l'exécution.

\n\n

Donc, écrire simplement let arr: [u8; 4] = slice ne fonctionnera pas. Le compilateur dira : « Désolé, je ne sais pas si ta tranche tiendra dans un tableau de 4 éléments ». Rust place la sécurité avant tout — si la tranche est plus courte, vous obtiendrez des déchets ou une panique.

\n\n

Méthode 1 : try_into() — la méthode moderne et sécurisée

\n\n

Depuis Rust 1.47, une manière élégante est apparue via le trait TryInto. C'est la méthode recommandée pour convertir une tranche en tableau. Elle retourne un Result, donc vous savez toujours si la conversion a réussi.

\n\n
use std::convert::TryInto;\n\nfn main() {\n    let slice: &[u8] = &[10, 20, 30, 40, 50];\n    \n    // On essaie d'obtenir un tableau de 3 éléments\n    let result: Result<[u8; 3], _> = slice[..3].try_into();\n    \n    match result {\n        Ok(arr) => println!("Tableau : {:?}", arr),\n        Err(_) => println!("Pas assez d'éléments !"),\n    }\n    \n    // Ou on utilise simplement unwrap si on est sûr\n    let arr: [u8; 4] = slice[..4].try_into().unwrap();\n    println!("Tableau de 4 : {:?}", arr);\n}
\n\n

Comment ça marche ? La méthode try_into() vérifie la longueur de la tranche à l'exécution. Si la longueur correspond, elle convertit ; sinon, elle retourne une erreur. C'est la solution idéale pour 99% des cas.

\n\n

Méthode 2 : copy_from_slice() — pour ceux qui aiment le contrôle

\n\n

Si vous avez déjà un tableau (par exemple, initialisé avec des zéros), vous pouvez copier les données de la tranche. Cette méthode exige que la tranche ne soit pas plus courte que le tableau — sinon, panique.

\n\n
fn main() {\n    let slice: &[u32] = &[100, 200, 300];\n    let mut arr: [u32; 3] = [0; 3]; // on crée un tableau vide\n    \n    arr.copy_from_slice(slice);\n    println!("Copié : {:?}", arr);\n    \n    // Si la tranche est plus longue — prenez un sous-ensemble\n    let long_slice = &[1, 2, 3, 4, 5];\n    let mut small_arr = [0u8; 2];\n    small_arr.copy_from_slice(&long_slice[..2]);\n    println!("Partie de la tranche : {:?}", small_arr);\n}
\n\n

Important : copy_from_slice fonctionne uniquement pour les types implémentant Copy (par exemple, les nombres). Pour les chaînes, il faut utiliser clone_from_slice.

\n\n

Méthode 3 : Itération manuelle — pour les extrémistes

\n\n

Parfois, on doit faire quelque chose de non standard. Par exemple, convertir une tranche en changeant l'ordre ou en filtrant. On peut alors itérer manuellement :

\n\n
fn slice_to_array<T: Copy, const N: usize>(slice: &[T]) -> Option<[T; N]> {\n    if slice.len() != N {\n        return None;\n    }\n    \n    let mut arr = [unsafe { std::mem::zeroed() }; N];\n    for (i, &val) in slice.iter().enumerate() {\n        arr[i] = val;\n    }\n    Some(arr)\n}\n\nfn main() {\n                

Blogs

Book Recommendations