Immutable vs const en Rust : pourquoi même les développeurs expérimentés se trompent-ils ?
\n\nAvez-vous déjà écrit en Rust et soudainement pensé : « Stop, j'ai déclaré une variable avec let, elle est immuable. Et const — c'est aussi une sorte de constante. Quelle est la différence alors ? ». Si oui — vous n'êtes pas seul. La question « What is the difference between immutable and const variables in Rust? » sur Stack Overflow a recueilli des milliers de vues. Et ce n'est pas un hasard.
À première vue, il semble que let x = 5 et const X: i32 = 5 fassent la même chose : ils interdisent de modifier la valeur. Mais en Rust, un langage où la sécurité mémoire et la performance sont primordiales, le diable se cache dans les détails. En 2025, comprendre ces détails n'est pas seulement une théorie, mais une nécessité pour écrire un code efficace et idiomatique.
Dans cet article, nous allons une fois pour toutes clarifier : en quoi une variable immutable diffère-t-elle d'une constante, quand utiliser quoi, et quelles sont les meilleures pratiques actuelles. C'est parti !
\n\n1. Compréhension de base : que dit le compilateur ?
\n\nCommençons par le plus simple. En Rust, les variables sont par défaut immuables. Cela signifie qu'après avoir assigné une valeur, vous ne pouvez pas la réécrire.
\n\nfn main() {\n let x = 5;\n // x = 6; // Erreur ! Impossible de modifier une variable immutable\n println!("x = {}", x);\n}\n\nEt voici un exemple avec une constante :
\n\nconst MAX_POINTS: u32 = 100_000;\n\nfn main() {\n println!("MAX_POINTS = {}", MAX_POINTS);\n}\n\nVisuellement, c'est similaire. Mais le compilateur Rust les traite de manière complètement différente. Et c'est là que les choses deviennent intéressantes.
\n\n1.1. Différence clé n°1 : où vivent-elles ?
\n\n- \n
let— déclare une variable. Elle existe dans la pile (ou le tas, s'il s'agit deBox,String, etc.) et a une adresse mémoire. On peut la référencer, la passer à des fonctions, la déplacer. \n const— déclare une constante. Elle n'a pas d'adresse mémoire fixe. Le compilateur inline (intègre) sa valeur directement dans le code à l'endroit où elle est utilisée. \n
C'est une différence fondamentale. const n'est pas une variable, c'est une valeur nommée qui est substituée à la compilation.
fn main() {\n let x = 42;\n let y = &x; // Ok, on prend une référence sur la variable\n\n const Z: i32 = 100;\n // let w = &Z; // Erreur ! La constante n'a pas d'adresse, impossible de prendre une référence\n}\n\n2. Approfondissement : performances et sémantique
\n\nMaintenant que nous connaissons le « lieu de résidence », examinons d'autres aspects importants.
\n\n2.1. Durée de vie et portée
\nLes constantes vivent dans la portée globale (ou à l'intérieur d'une fonction, mais avec une durée de vie static). Elles existent pendant toute la durée d'exécution du programme. On peut les déclarer en dehors d'une fonction, et elles seront accessibles partout.
Les variables immutables ne vivent qu'à l'intérieur d'un bloc (fonction, boucle, if). Dès que le bloc se termine, la mémoire est libérée.
const GLOBAL_CONST: i32 = 10;\n\nfn main() {\n let local_var = 20;\n // local_var ne vit qu'à l'intérieur de main\n}\n// local_var n'existe plus\n// GLOBAL_CONST est toujours accessible\n\n2.2. Type et annotations
\nPour const, il est obligatoire de spécifier le type de données. Pour let, le compilateur le déduira lui-même.
const PI: f64 = 3.14159; // Obligatoire : const NOM: Type = valeur;\nlet pi = 3.14159; // Le compilateur comprendra tout seul que c'est un f64\n\n2.3. Évaluation à la compilation (CTFE)
\nLa valeur de const doit être évaluée à la compilation.