Les tableaux en Rust
Un tableau (array) est une liste de valeurs de taille fixe, toutes du même type. « Taille fixe » est le mot important : une fois le tableau créé, il ne peut ni grandir ni rétrécir. Si vous avez besoin de quelque chose qui change de taille, c’est le rôle du vecteur.
Créer un tableau
Section intitulée « Créer un tableau »fn main() { let numbers: [i32; 5] = [1, 2, 3, 4, 5]; println!("{:?}", numbers);}Le type [i32; 5] se lit « un tableau de 5 valeurs i32 ». Cette longueur fait partie du type : un [i32; 5] et un [i32; 3] sont considérés comme des types différents.
Vous pouvez aussi laisser Rust deviner le type et écrire seulement les valeurs :
let numbers = [1, 2, 3, 4, 5];La même valeur, répétée
Section intitulée « La même valeur, répétée »Pour remplir un tableau avec la même valeur N fois, utilisez ce raccourci :
fn main() { let zeros = [0; 5]; // [0, 0, 0, 0, 0] println!("{:?}", zeros);}Accéder aux éléments
Section intitulée « Accéder aux éléments »Les indices d’un tableau commencent à 0, et on les écrit entre crochets :
fn main() { let fruits = ["pomme", "banane", "cerise"];
println!("{}", fruits[0]); // pomme println!("{}", fruits[2]); // cerise println!("Longueur : {}", fruits.len());}Les accès hors limites sont interceptés
Section intitulée « Les accès hors limites sont interceptés »Si vous essayez d’accéder à un indice qui n’existe pas, Rust arrête votre programme au lieu de lire en douce de la mémoire n’importe comment :
fn get_fruit(fruits: [&str; 3], index: usize) -> &str { fruits[index]}
fn main() { let fruits = ["pomme", "banane", "cerise"]; println!("{}", get_fruit(fruits, 10)); // panique à l'exécution}thread 'main' (12345) panicked at src/main.rs:2:5:index out of bounds: the len is 3 but the index is 10Ce message vient de Rust lui-même, qui l’affiche toujours en anglais. Il dit que le thread main a paniqué (panic) à la ligne 2, car l’indice est hors limites (index out of bounds) : la longueur est 3, mais l’indice vaut 10.
Parcourir un tableau
Section intitulée « Parcourir un tableau »fn main() { let numbers = [10, 20, 30];
for n in numbers { println!("{n}"); }}Des tableaux de tableaux (tableaux 2D)
Section intitulée « Des tableaux de tableaux (tableaux 2D) »Un tableau peut contenir d’autres tableaux. Vous obtenez alors une grille avec des lignes et des colonnes, comme un plateau de jeu ou une petite feuille de calcul. Le type de grid ci-dessous est [[i32; 3]; 2], qui se lit « 2 lignes, chacune étant un tableau de 3 valeurs i32 ».
fn main() { // 2 lignes, 3 colonnes let grid = [ [1, 2, 3], [4, 5, 6], ];
println!("Ligne 1, colonne 2 : {}", grid[1][2]);
let mut total = 0; for row in grid { println!("{:?}", row); for value in row { total += value; } } println!("Total : {total}");}Sortie :
Ligne 1, colonne 2 : 6[1, 2, 3][4, 5, 6]Total : 21grid[1][2] signifie « la ligne 1, puis la colonne 2 dans cette ligne ». Les deux comptent à partir de 0 : c’est donc la deuxième ligne, troisième valeur. Pour visiter chaque valeur, utilisez une boucle pour les lignes et, à l’intérieur, une deuxième boucle pour les valeurs de chaque ligne.
Toutes les lignes doivent avoir la même longueur, car la longueur d’une ligne fait partie du type. Si vous avez aussi besoin de la position pendant la boucle, .iter().enumerate() vous donne l’indice et la valeur ensemble. C’est expliqué à la page boucle for.
Tableaux ou vecteurs ?
Section intitulée « Tableaux ou vecteurs ? »Utilisez un tableau quand la taille est fixe et connue à l’avance (comme les sept jours de la semaine). Utilisez un Vec quand vous devez ajouter ou retirer des éléments, ce qui, en pratique, arrive la plupart du temps. Dans le code Rust de tous les jours, on croise moins souvent des tableaux que des vecteurs.
Exercices
Section intitulée « Exercices »1. Somme et moyenne
Section intitulée « 1. Somme et moyenne »Créez le tableau [4, 8, 15, 16, 23, 42]. Additionnez toutes les valeurs, puis affichez la somme et la moyenne avec deux décimales. Indice : parcourez-le avec for, gardez un total cumulé, et convertissez les deux nombres en f64 avec as avant de diviser.
Voir la solution
fn main() { let numbers = [4, 8, 15, 16, 23, 42];
let mut total = 0; for n in numbers { total += n; }
let average = total as f64 / numbers.len() as f64; println!("Somme : {total}"); println!("Moyenne : {average:.2}");}Sortie :
Somme : 108Moyenne : 18.00Sans as f64, total / numbers.len() serait une division entière, et Rust se plaindrait en plus que total (un i32) et len() (un usize) ne sont pas du même type.
2. Le jour le plus chaud
Section intitulée « 2. Le jour le plus chaud »Vous avez les températures d’une semaine : [18, 25, 12, 31, 22, 27, 19]. Trouvez la plus élevée et affichez-la. Indice : commencez par let mut hottest = temps[0];, puis parcourez le tableau et remplacez la valeur chaque fois que vous en trouvez une plus grande.
Voir la solution
fn main() { let temps = [18, 25, 12, 31, 22, 27, 19];
let mut hottest = temps[0]; for t in temps { if t > hottest { hottest = t; } }
println!("Jour le plus chaud : {hottest}");}Sortie :
Jour le plus chaud : 31Partir de temps[0] plutôt que de 0 a son importance : si toutes les températures étaient négatives, partir de 0 donnerait une mauvaise réponse.
Récapitulatif
Section intitulée « Récapitulatif »- Les tableaux ont une longueur fixe qui fait partie de leur type :
[i32; 5]. - On accède aux éléments avec
tableau[indice], en commençant à 0. - Un accès hors limites provoque une panique à l’exécution au lieu d’un comportement indéfini.
- Un tableau peut contenir des tableaux :
[[i32; 3]; 2]est une grille qu’on lit avecgrid[ligne][colonne]. - Si vous devez changer la taille, utilisez plutôt un
Vec.
Petit quiz
Section intitulée « Petit quiz »Petit quiz
1. Qu'est-ce qui est vrai à propos de la longueur d'un tableau en Rust ?
2. Que se passe-t-il quand on accède, à l'exécution, à un indice hors des limites du tableau ?
3. Que crée let zeros = [0; 5]; ?
Score : 0 / 3
Pour aller plus loin
Section intitulée « Pour aller plus loin »- The Array Type — The Rust Book (en anglais) : la présentation officielle des tableaux, y compris la raison pour laquelle la longueur fait partie du type.
- Arrays and Slices — Rust by Example (en anglais) : de courts exemples exécutables, et un premier aperçu des slices.
- Looping Through a Collection with
for— The Rust Book (en anglais) : pourquoi une boucleforest plus sûre que parcourir un tableau avec un indice. array— documentation de la bibliothèque standard (en anglais) : ce que savent faire les tableaux, commemapetas_slice, et comment ils profitent aussi de toutes les méthodes des slices.