Blog ENI : Toute la veille numérique !
💥 Un livre PAPIER acheté
= La version EN LIGNE offerte pendant 1 an !
Accès illimité 24h/24 à tous nos livres & vidéos ! 
Découvrez la Bibliothèque Numérique ENI. Cliquez ici
  1. Livres et vidéos
  2. Rust
  3. Les vecteurs en langage Rust
Extrait - Rust Développez des programmes robustes et sécurisés
Extraits du livre
Rust Développez des programmes robustes et sécurisés
4 avis
Revenir à la page d'achat du livre

Les vecteurs en langage Rust

Introduction

Pour le moment, nous avons principalement rencontré un type de collection en Rust : le vecteur. De fait, il est non seulement le type de collection le plus intuitif et le plus rapidement utilisable, mais il est surtout au cœur de la définition du type String étudié précédemment.

Il y a cependant beaucoup plus à découvrir : outre le vecteur, nous aborderons dans le chapitre suivant diverses structures semblables à des tables de hachage.

Bien sûr, on reste en Rust : donc l’emprunt et la propriété demeurent fondamentaux. Le stockage en mémoire est donc vérifié à la compilation, y compris, bien évidemment, pour les collections.

Le présent chapitre est donc construit comme un inventaire des principales fonctionnalités relatives au vecteur en Rust. Le chapitre suivant nous permettra d’étudier les trois autres principales collections, en tout cas les plus couramment utilisées : le vecteur Vec, la HashMap (table de paires clé/valeur, comme une sorte de dictionnaire Python ou C#) et le HashSet (ensemble de valeurs similaires au Set du langage Python).

Passons d’emblée au vecteur.

Le vecteur Vec<T>

1. Introduction

Nous avons déjà abordé l’implémentation mémoire d’un vecteur en Rust. Il s’agit d’une sorte de triplet stocké dans la pile, composé des éléments suivants :

  • Le pointeur vers la zone de stockage du vecteur dans le tas.

  • La taille courante, c’est-à-dire la longueur du contenu du vecteur à l’instant t.

  • La capacité, c’est-à-dire la taille déjà allouée dans le tas. Cette capacité est égale ou supérieure à la taille courante.

À propos de la capacité : un vecteur étant une sorte de tableau redimensionnable, si on a une idée de la taille usuelle ou moyenne du vecteur à l’exécution, il est intéressant de dimensionner d’emblée la capacité au niveau envisagé.

On crée un projet pour manipuler des vecteurs en Rust :

cargo new vecteurs --bin 
>     Created binary (application) `vecteurs` package 

Nous commençons par instancier plusieurs vecteurs, parfois en précisant le type des éléments, parfois non. À chaque création de vecteurs, on affichera le type créé, la longueur du vecteur et sa capacité.

Pour le type, on met à disposition du programme cette petite fonction capable de nous retourner le type du vecteur :

fn obtenir_type<T>(_: &T) { 
    println!("Type : {}", unsafe {  std::any::type_name::<T>() }); 
} 

On utilise pour cela la méthode type_name documentée ici : https://doc.rust-lang.org/std/any/fn.type_name.html

Dans une fonction nommée instanciations_vecteurs, on crée plusieurs vecteurs et pour chacun on observera le type, la longueur et la capacité :

  • Un vecteur d’entiers, mais avec type implicite (on ne précise pas le type inclut dans le vecteur.

  • Un vecteur d’entiers i64, ce dernier type étant précisé explicitement. Notons que ce vecteur est vide.

  • Un vecteur de mots, sans préciser le type. Nous sommes dans le cas où le vecteur contient in fine des chaînes de caractères de type &str. On le vérifiera.

  • Un autre vecteur de mots...