En Rust, il existe deux principales manières de stocker des données immuables tout au long de l'exécution du programme : const et static.
Constante (const) — c'est une valeur immuable calculée au moment de la compilation. Elle doit toujours être explicitement typée et initialisée avec une expression constante (qui peut être calculée à l'étape de la compilation). Les constantes n'ont pas d'adresse fixe en mémoire et sont « insérées » par le compilateur aux endroits où elles sont utilisées.
const MAX_ATTEMPTS: u32 = 5;
Variable statique (static) stocke une valeur dans une zone de mémoire spécifique tout au long de l'exécution du programme. Son adresse est fixe, et elle peut être mutable (en utilisant static mut), mais elle doit être manipulée avec des précautions particulières en raison des potentielles courses de données dans des scénarios multithreads.
static APP_NAME: &str = "MyApp"; static mut COUNTER: u32 = 0;
const lorsque la valeur doit être toujours connue à la compilation et qu'un stockage global n'est pas nécessaire.static si un seul emplacement de stockage en mémoire est requis, auquel tous les modules peuvent accéder, ou si la valeur ne peut pas être calculée à l'étape de la compilation.Quelle est la différence entre
constetstaticen Rust ? Une variable statique peut-elle faire référence à une non-constante ?
Réponse : La principale différence réside dans la portée de stockage (durée de vie) : const ne garantit pas l'existence dans la mémoire (c'est un remplacement de valeur), alors que static est un objet qui vit tout au long du programme avec une adresse fixe.
Une variable statique ne peut se voir assigner que des valeurs connues à l'étape de la compilation :
let a = 42; // static INVALID: i32 = a; // Erreur ! Seules les constantes sont autorisées.
Histoire
Dans un projet de service backend pour la répartition de la charge, l'un des développeurs a utilisé static mut pour un compteur commun d'appels depuis différents threads, sans utiliser de synchronisation. Cela a entraîné des courses de données et des résultats imprévisibles — certaines requêtes étaient simplement perdues. La solution — utiliser des types atomiques de std::sync::atomic, ou Mutex.
Histoire
Un jeune développeur a décidé de placer une chaîne de bienvenue de l'utilisateur dans une constante à l'aide de const, mais a tenté de l'associer au résultat d'une fonction, calculée au moment de l'initialisation. Le compilateur a renvoyé une erreur parce que la valeur devait être définie à la compilation. La raison — la constante doit être calculable à l'étape de compilation, alors que la fonction renvoie une valeur au moment de l'exécution.
Histoire
Dans un ancien projet, toutes les valeurs globales ont été remplacées par static, oubliant que les littéraux de chaîne avec des références utilisent l'espace mémoire du programme, et que certaines déclarations nécessitaient en réalité seulement un remplacement de valeur : cela a augmenté la taille du binaire et compliqué la gestion de la mémoire. En fin de compte — augmentation du temps de démarrage et fuites lors du chargement dynamique des bibliothèques.