Die konstante Auswertung in Rust ermöglicht es, einen Teil der Berechnungen oder Initialisierungen zur Kompilezeit durchzuführen, anstatt zur Laufzeit des Programms.
const PI: f64 = 3.1415;
static mut GLOBAL_COUNTER: i32 = 0;
const fn ist eine Funktion, deren Ergebnis zur Festlegung eines Wertes für const oder static verwendet werden kann. Solche Funktionen können im konstanten Kontext aufgerufen werden.
const fn factorial(n: usize) -> usize { if n == 0 { 1 } else { n * factorial(n - 1) } } const FACT_5: usize = factorial(5); // Kompiliert!
Einschränkungen von const fn:
Box::new usw.) sind nicht erlaubt,Frage: Kann man jede Funktion im const-Kontext verwenden, wenn ihr Ergebnis nicht verändert wird? Zum Beispiel so:
fn add(a: i32, b: i32) -> i32 { a + b } const RES: i32 = add(1, 2);
Typische falsche Antwort: Ja, denn die Funktion ist rein und das Ergebnis ist im Voraus bekannt.
Richtige Antwort: Nein, die Funktion muss ausdrücklich als const fn deklariert werden, nur dann kann sie innerhalb einer const-Initialisierung aufgerufen werden. Normale Funktionen werden nur zur Laufzeit aufgerufen!
Beispiel:
const fn add(a: i32, b: i32) -> i32 { a + b } const RES: i32 = add(1, 2); // Kompiliert!
Geschichte
In einem Projekt mit Berechnungen der dreidimensionalen Geometrie versuchte ein Entwickler, eine Wertetabelle über das Ergebnis eines Aufrufs einer normalen Funktion und nicht einer const fn zu deklarieren. Infolgedessen traten Kompilierungsfehler auf, und der Vorteil der Berechnung zur Kompilezeit ging verloren.
Geschichte
Die Verwendung von static mut für einen globalen Cache führte zu Datenrennen beim Zugriff aus mehreren Threads (static mut ist nicht sicher!). Man hätte Atomic oder Mutex verwenden müssen, um den Zugriff auf die globale Ressource zu synchronisieren.
Geschichte
Um die Initialisierung großer Arrays zu beschleunigen, wurden sie als static deklariert, aber es wurde vergessen, dass static immer eine feste Adresse hat, weshalb die Daten nicht wie lokal im Prozessorcache landeten und die Operationen auf dem heißen Logikpfad des Servers langsamer wurden. Man hätte lokale let-Ausdrücke mit Berechnungen zur Laufzeit verwenden müssen.