Le typage de Rust

Par mlemay, 22 février, 2025

Déclaration

Dans le langage Rust, on déclare une variable avec let suivit de la valeur de la variable ou de son type et de sa valeur. On peut omettre le type de la variable car Rust est capable de l’inférer s’il a sa valeur. Il est parfois utile de le spécifier, par exemple pour préciser la taille d’un entier. Toutes les variables sont immuables par défaut. C’est-à-dire que leurs valeurs ne peuvent changer après la déclaration. On peut toutefois rendre une variable mutable en ajoutant mut avant le nom de la variable dans sa déclaration. Cela ne devrait être fait avec parcimonie car le but de l’immuabilité est d’améliorer la sécurité du code. On peut également déclarer des constantes en utilisant const au lieu de let. Les constantes ne peuvent pas être muables et doivent toujours avoir une valeur et le type lors de la déclaration. (Note : Dans certains les extrait de codes suivant, la fonction main ne sera pas affichée pour améliorer la visibilité)

//une variable immuable
let x1 = 5;
let x3 : i32 = 5;
//une variable muable
let mut y = 5;
y = 6;	// comme la variable est muable, on peut lui donner une nouvelle valeur
//une constante
const SECONDES_PAR_JOURS: u32 = 60 * 60 * 24;

Masquage

EN Rust, on peut déclarer une variable avec le même nom plusieurs fois. Dans ce cas, la dernière variable déclaré est celle qui est utilisée. On dit qu’elle masque la variable précédente. Le masquage est démarque d’une variable muable car il permet de changer son typage. Ceci est un code valide.

let espaces = "                ";
let espaces = espaces.len();

Alors que ce code ne compile pas.

let  mut espaces = "                ";
lespaces = espaces.len();

Noter que comme la portée d’une variable est limité à l'intérieur de la fonction où elle est déclarée, la même variable peut être utilisée plusieurs fois et donner des valeurs différentes. Par exemple

fn main() {
    let x = 5;
    let x = x + 1;
    {
        let x = x * 2;
        println!("La valeur de x dans la portée interne est : {}", x);
    }
    println!("La valeur de x est : {}", x);
}
La valeur de x dans la portée interne est : 12
La valeur de x est : 6

Typage

Rust a quatre type scalaires principaux: entier, flottant, booléen et charactères.

Entiers

Un entier est un nombre sans partie décimale. Il existe deux types d’entiers : signé (i) et non signé (u). Les entiers signés peuvent être négatifs ou positifs tandis que les entiers non signés sont toujours positifs. On peut utiliser les entiers non signés pour s’assurer qu’une valeur ne passe jamais sous zéro sans faire de tests. On précise également combien de bits doivent être utilisés pour représenter la valeur soit 8,16, 32, 64 ou128. Par défaut Rust utilise i32.

Taille Signé Non signé
8 bits i8 u8
16 bits i16 u16
32 bits i32 u32
64 bits i64 u64
128 bits i128 u128

Il faut faire attention de ne pas utiliser une taille trop petite ou on risque le dépassement, ce qui crée une erreur.

let nombre_positif : u32 = 444;
let nombre_negatif : i8 = -2;

Flottants

Pour les nombres avec décimale, on utilise plutôt les flottants. Il y a deux type f64 et f32 et f64 est le type par défaut.

let x = 5.34;	//f64
let y : f32 = 6.9;

Booléens

Les booléens sont des variables qui ont deux valeurs possibles : vrai ou faux. Rust les déclare comme dans la majorité des langages avec bool.

let t = true;
let f: bool = false; 

Caractères et Strings

Les caractères sont mis entre des guillemets simple et déclarés avec char. Chacun a pour valeur un caractère de l’Unicode, ce qui inclus les alphabets de toutes les langues et le émojis. Comme les programmeurs doivent souvent traiter du texte plutôt que des caractères uniques, ils se tournent vers les Strings et les slices (&str).
Les slices ne sont pas modifiables et elles sont donc utilisées pour l’affichage, et l’analyse. On les déclare avec les doubles guillemets. Les String ne font pas parti du noyau Rust, elles viennent de la bibliothèque standard. Elles sont considérées comme une collection, elles peuvent être modifiées et agrandies. Elles sont idéales pour les interactions avec l’utilisateurs.

//caractère
let z = 'Z';
let bisou : char = '💋';
//création d’une slice
let donnee : &char = "contenu initial";
//deux méthode pour créer une String
let mut s1 = String::new();
let s1 = donnee.to_string();
let s2: String = String::from("contenu initial");

Rust utilise aussi plusieurs types composés. Ils sont utilisés pour regrouper plusieurs valeurs dans une seule variable.

Tuple

Un tuple est une liste de taille fixe qui peut avoir des valeurs de type différents. On le déclare avec des parenthèses et des virgules entre chaque élément. Pour accéder à un élément en particulier, on appelle le tuple suivi d’un point et de l’indice de l’élément désiré.

let x: (i32, bool, char) = (500, true, 'a' '');
let nombre = x.0;
let bool= x.1;
let lettre = x.2;

Tableau

Un tableau est une liste de taille fixe dont tous les attributs doivent être du même type. On le déclare avec des crochets et des virgules entre chaque élément. Pour accéder à un élément en particulier, on appelle le tableau suivi de l’indice de l’élément désiré entre crochets.

let a = [1, 2, 3, 4, 5];
let b: [i32; 5] = [1, 2, 3, 4, 5];
let premier = a[0];

Vecteurs

Si on veut une collection de données avec un taille qui n’est pas fixée lors de la déclaration, on peut utiliser un vecteur. Les vecteurs sont fournis par la bibliothèque standard. Tout comme les Strings se sont des collections et ils peuvent être modifiés.

//créer un vecteur vide et lui ajouter des valeurs
let mut v : Vec<i32> = Vec::new();
v.push(1);
v.push(2);
v.push(3);
//utiliser la macro
let v2 = vec![1, 2, 3, 4, 5];

Sources


Étiquettes

Commentaires1

mhassouna

il y a 1 mois

Le texte fait un excellent travail pour expliquer les concepts de Rust de manière simple et compréhensible. Il serait peut-être utile de souligner davantage l’importance de l’immuabilité dans la philosophie de Rust, mais autrement, tout semble très clair pour un apprenant !