Aller au contenu

Les types de données en Rust

En Rust, chaque valeur a un type : une étiquette qui indique au compilateur de quelle sorte de donnée il s’agit (un nombre entier, un nombre à virgule, du texte, vrai/faux, etc.). Connaître le type permet à Rust de vérifier votre code avant qu’il ne s’exécute.

Comme vous l’avez vu avec les variables, Rust peut en général déduire le type pour vous (c’est l’inférence de type). Mais il est utile de connaître les principaux types par leur nom, car vous les verrez dans les messages d’erreur et dans les signatures de fonctions.

Les entiers sont des nombres sans virgule, comme 42 ou -7. Rust a plusieurs types d’entiers, qui diffèrent par leur taille et par le fait qu’ils acceptent ou non les nombres négatifs :

Type Signé ? Usage typique
i32 Oui (peut être négatif) Le type par défaut : utilisez-le sauf si vous avez une raison de faire autrement
u32 Non (0 et plus) Compteurs, tailles, tout ce qui ne peut pas être négatif
i64 / u64 Oui / Non Très grands nombres
usize Non Indices dans les collections
fn main() {
let temperature = -5; // i32 par défaut
let count: u32 = 100; // explicitement non signé
println!("{temperature} degrés, le compteur vaut {count}");
}

Sortie :

-5 degrés, le compteur vaut 100
▶ Essayez par vous-même

Pour les nombres à virgule, on utilise les types à virgule flottante. Il y en a deux : f64 (le type par défaut, en double précision) et f32.

fn main() {
let pi = 3.14159; // f64 par défaut
let price: f32 = 9.99;
println!("Pi vaut {pi}, le prix est de {price}");
}

Sortie :

Pi vaut 3.14159, le prix est de 9.99
▶ Essayez par vous-même

Attention : dans le code, Rust écrit toujours les décimales avec un point (3.14), jamais avec une virgule. Restez sur f64, sauf si vous avez précisément besoin du f32, plus petit : f64 est plus précis et tout aussi rapide sur le matériel moderne.

Un booléen (bool) est le type le plus simple : il vaut soit true (vrai), soit false (faux). Vous en utiliserez sans arrêt dans les if et les conditions.

fn main() {
let is_logged_in = true;
let has_permission: bool = false;
println!("connecté : {is_logged_in}, autorisation : {has_permission}");
}

Sortie :

connecté : true, autorisation : false
▶ Essayez par vous-même

Un char contient un seul caractère, écrit entre apostrophes ' '. Un char Rust peut être n’importe quelle valeur scalaire Unicode, ce qui couvre la plupart des emoji. Quelques emoji complexes (comme les drapeaux, ou ceux formés de plusieurs caractères assemblés) ne tiennent cependant pas dans un seul char.

fn main() {
let letter = 'R';
let symbol = '$';
let crab = '🦀';
println!("{letter} {symbol} {crab}");
}

Sortie :

R $ 🦀
▶ Essayez par vous-même

En Rust, le texte s’écrit entre guillemets doubles. Vous rencontrerez deux types de chaînes :

  • &str : une string slice (tranche de chaîne), en général du texte écrit directement dans votre code (un « littéral de chaîne »).
  • String : un texte extensible, dont vous êtes propriétaire, que vous pouvez modifier et compléter.
fn main() {
let greeting = "Bonjour"; // &str
let mut name = String::from("Ferris"); // String
name.push_str(" le crabe"); // une String peut grandir
println!("{greeting}, {name} !");
}

Sortie :

Bonjour, Ferris le crabe !
▶ Essayez par vous-même

Ne vous souciez pas encore de la différence entre &str et String : elle est liée à l’ownership (possession), que vous apprendrez bientôt. Pour l’instant : utilisez "..." pour du texte, et prenez String quand vous devez le construire ou le modifier.

La plupart du temps, Rust déduit le type. Mais il a parfois besoin d’un coup de pouce, par exemple pour convertir du texte en nombre (vous le verrez à la page Conversion de types en Rust). On ajoute un type avec deux-points :

let x: i32 = 42;
let y: f64 = 3.5;
let active: bool = true;
Type Ce qu’il contient Exemple
i32 Nombre entier (par défaut) let n = 42;
u32 Nombre entier positif ou nul let n: u32 = 42;
f64 Nombre à virgule (par défaut) let pi = 3.14;
bool true ou false let ok = true;
char Un caractère let c = 'A';
&str Littéral de texte let s = "salut";
String Texte extensible let s = String::from("salut");

Décrivez un personnage de jeu avec une variable de chaque type : un nom (&str), un niveau (i32), un pourcentage de santé (f64), un indicateur is_online (bool) et une lettre de rang (char). Affichez-les tous sur une seule ligne. Indice : un char s’écrit entre apostrophes, le texte entre guillemets doubles.

Voir la solution
fn main() {
let name = "Ferris"; // &str
let level = 7; // i32
let health = 82.5; // f64
let is_online = true; // bool
let rank = 'A'; // char
println!("{name} | niveau {level} | {health} % | en ligne : {is_online} | rang {rank}");
}

Sortie :

Ferris | niveau 7 | 82.5 % | en ligne : true | rang A
▶ Essayez par vous-même

Commencez par String::from("Rust"), ajoutez-y " est rapide" puis " et sûr", et affichez le résultat. Indice : la String doit être déclarée avec mut pour que push_str puisse la modifier.

Voir la solution
fn main() {
let mut sentence = String::from("Rust");
sentence.push_str(" est rapide");
sentence.push_str(" et sûr");
println!("{sentence}");
}

Sortie :

Rust est rapide et sûr
▶ Essayez par vous-même
  • Chaque valeur a un type ; Rust le déduit en général tout seul.
  • Nombres entiers → i32 (par défaut). Nombres à virgule → f64 (par défaut).
  • bool vaut true/false ; char est un seul caractère entre apostrophes.
  • Le texte s’écrit entre guillemets doubles : &str pour les littéraux, String pour le texte extensible.

Petit quiz

1. Quel est le type entier par défaut en Rust si vous n’en précisez aucun ?

2. Comment Rust distingue-t-il un littéral char d’un littéral de chaîne ?

3. Quel type représente un texte extensible, dont on est propriétaire, et qu’on peut modifier ?

4. Quel est le type à virgule flottante par défaut en Rust ?

5. Quel type Rust déduit-il pour let greeting = "Bonjour"; ?

Score : 0 / 5