In Rust gibt es zwei Hauptmethoden zur Speicherung unveränderlicher Daten während der Programmausführung: const und static.
Konstante (const) — dies ist ein unveränderlicher Wert, der zur Compile-Zeit berechnet wird. Sie muss immer explizit typisiert sein und mit einem konstanten Ausdruck initialisiert werden (der zur Compile-Zeit berechnet werden kann). Konstanten haben keine feste Speicheradresse und werden vom Compiler an den Verwendungsorten „eingefügt“.
const MAX_ATTEMPTS: u32 = 5;
Statische Variable (static) speichert einen Wert in einem bestimmten Speicherbereich während der gesamten Programmausführung. Ihre Adresse ist fest, und sie kann veränderlich sein (unter Verwendung von static mut), jedoch muss auf sie mit besonderen Vorsichtsmaßnahmen zugegriffen werden, da es in mehrfädigen Szenarien zu Datenrennen kommen kann.
static APP_NAME: &str = "MyApp"; static mut COUNTER: u32 = 0;
const, wenn der Wert immer zur Compile-Zeit bekannt sein muss und kein globaler Speicher erforderlich ist.static, wenn ein einzelner Speicherort im Speicher benötigt wird, auf den alle Module zugreifen können, oder wenn der Wert nicht zur Compile-Zeit berechnet werden kann.Was ist der Unterschied zwischen
constundstaticin Rust? Kann eine statische Variable auf eine Nicht-Konstante verweisen?
Antwort: Der Hauptunterschied ist der Speicherbereich (Lebensdauer): const garantiert nicht die Existenz im Speicher (es ist eine Wertsubstitution), während static ein Objekt ist, das während der gesamten Programmausführung mit einer festen Adresse lebt.
Eine statische Variable kann nur einen Wert zugewiesen bekommen, der zur Compile-Zeit bekannt ist:
let a = 42; // static INVALID: i32 = a; // Fehler! Nur Konstanten sind zulässig.
Geschichte
In einem Backend-Service-Projekt zur Lastverteilung verwendete einer der Entwickler static mut für einen gemeinsamen Zähler von Anfragen aus verschiedenen Threads, ohne Synchronisierung zu verwenden. Dies führte zu Datenrennen und unvorhersehbaren Ergebnissen — einige Anfragen gingen einfach verloren. Lösung — Verwendung atomarer Typen aus std::sync::atomic oder Mutex.
Geschichte
Ein junger Entwickler beschloss, die Begrüßungsnachricht für den Benutzer in eine Konstante mit const zu extrahieren, versuchte jedoch, sie mit dem Ergebnis einer Funktion zu verknüpfen, die zur Initialisierungszeit berechnet wird. Der Compiler erzeugte einen Fehler, weil der Wert zur Compile-Zeit definiert sein musste. Der Grund — eine Konstante muss zur Compile-Zeit berechnet werden können, während eine Funktion den Wert zur Laufzeit zurückgibt.
Geschichte
In einem alten Projekt wurden alle globalen Werte durch static ersetzt, wobei vergessen wurde, dass String-Literale mit Verweisen den Speicherbereich des Programms verwenden und einige Deklarationen tatsächlich nur eine Wertsubstitution erforderten: Dies erhöhte die Größe des Binaries und erschwerte die Speicherverwaltung. Ergebnis — Anstieg der Startzeit und Speicherlecks bei dynamischem Laden von Bibliotheken.