Variables et Mutabilité
En Rust, la sécurité et la gestion de la mémoire guident chaque choix de conception.
L’immutabilité est le comportement par défaut.
L’Immutabilité par défaut
Lorsque nous déclarons une variable avec le mot-clé let, sa valeur est verrouillée. Toute tentative de modification dans le code provoque une erreur de compilation.
fn main() {
let x = 5;
println!("La valeur de x est : {x}");
// COMPILER ERROR: cannot assign twice to immutable variable `x`
// x = 6;
}
Ce comportement garantit qu’une donnée ne changera pas de manière imprévisible au cours de l’exécution, éliminant ainsi toute une classe de bogues.
Rendre une variable mutable
Pour autoriser explicitement la modification d’une variable, il faut utiliser le mot-clé mut. Cela documente clairement l’intention du code pour le développeur et pour le compilateur.
fn main() {
let mut x = 5;
println!("Valeur initiale : {x}");
x = 6; // Totalement valide
println!("Nouvelle valeur : {x}");
}
Le Masquage (Shadowing)
Le masquage (shadowing) consiste à déclarer une nouvelle variable avec le même nom qu’une variable existante.
La variable suivante masque (« remplace ») la première.
fn main() {
let spaces = " "; // Type: &str (chaîne de caractères)
// On transforme la donnée sans créer un nouveau nom (ex: spaces_len)
let spaces = spaces.len(); // type: usize (entier)
println!("Nombre d'espaces : {spaces}"); // Affiche « Nombre d'espaces : 3 »
}
Pourquoi utiliser le shadowing ?
- Transformation de type : Le masquage permet de réutiliser un nom d’une variable logique après avoir transformé ou nettoyé une donnée (par exemple lors de l’ouverture d’un fichier ou de la conversion (parsing) d’une chaîne de caractères en entier).
- Préservation de l’immutabilité : chaque étape du shadowing crée une variable immuable. La donnée ne peut pas être modifiée par accident.
Constantes vs Variables immuables
Il ne faut pas confondre une variable immuable (let x: u32 = 5;) avec une constante (const Y: u32 = 5;).
| Caractéristique | Variable Immuable (let) | Constante (const) |
|---|---|---|
| Mutabilité | Peut être masquée (shadowing) | Strictement immuable |
| Évaluation | À l’exécution (runtime) | À la compilation (compile-time) |
| Type | Optionnel (inféré par le compilateur) | Obligatoire (toujours explicite) |
| Scope | Local au bloc de code | Global ou local |
// Une constante globale, évaluée à la compilation
const SECOUNDS_IN_HOUR: u32 = 60 * 60;
fn main() {
println!("Secondes par heure : {SECOUNDS_IN_HOUR}");
}