Rust - Grundlagen - 01 - Variablenbeschattung

Variablenbeschattung

Verständnis

Wenn in Rust eine Variable (let oder let mut) a später erneut deklariert wird, nennt man dieses Verhalten Shadowing (Beschattung).

  • const-Konstanten können nicht beschattet werden.
  • Shadowing kann einen Blockbereich ({}) haben.
  • Bei gleichem Variablennamen kann gleichzeitig ein neuer Datentyp deklariert werden.

Quelle

https://doc.rust-lang.org/book/ch03-01-variables-and-mutability.html#shadowing

fn main() {
    let x = 5;

    let x = x + 1;

    {
        let x = x * 2;
        println!("The value of x in the inner scope is: {}", x);
    }

    println!("The value of x is: {}", x);
}

Dieses Programm bindet x zunächst an den Wert 5. Danach wird x durch die erneute Verwendung von let x = beschattet: Der ursprüngliche Wert wird um 1 erhöht, sodass x nun 6 ist. In einem inneren Bereich beschattet die dritte let-Anweisung x erneut und multipliziert den vorherigen Wert mit 2, wodurch x den Wert 12 erhält. Nach Ende dieses Bereichs endet die innere Beschattung und x wird wieder zu 6. Die Ausgabe lautet:


$ cargo run
   Compiling variables v0.1.0 (file:///projects/variables)
    Finished dev [unoptimized + debuginfo] target(s) in 0.31s
     Running `target/debug/variables`
The value of x in the inner scope is: 12
The value of x is: 6

Shadowing unterscheidet sich von mut, weil ein Kompilierzeitfehler entsteht, wenn wir die Variable versehentlich ohne das Schlüsselwort let erneut zuweisen. Mit let können wir einen Wert mehrfach umformen und die Variable nach Abschluss dieser Umformungen unveränderlich lassen.

Der andere Unterschied zwischen mut und Shadowing besteht darin, dass wir mit einer erneuten Verwendung von let effektiv eine neue Variable erzeugen. Dadurch können wir den Typ des Werts ändern und denselben Namen wiederverwenden. Angenommen, unser Programm fragt einen Benutzer, wie viele Leerzeichen zwischen Text stehen sollen, indem er Leerzeichen eingibt; wir möchten diese Eingabe aber als Zahl speichern:


    let spaces = "   ";
    let spaces = spaces.len();

Diese Konstruktion ist erlaubt, weil die erste Variable spaces vom String-Typ ist und die zweite, völlig neue Variable mit demselben Namen den Zahlentyp hat. Shadowing erspart uns Namen wie spaces_str und spaces_num; stattdessen können wir den einfacheren Namen spaces wiederverwenden. Wenn wir dafür jedoch mut verwenden, entsteht ein Kompilierzeitfehler:


    let mut spaces = "   ";
    spaces = spaces.len();

Die Fehlermeldung sagt, dass der Typ einer Variable nicht geändert werden darf:


$ cargo run
   Compiling variables v0.1.0 (file:///projects/variables)
error[E0308]: mismatched types
 --> src/main.rs:3:14
  |
3 |     spaces = spaces.len();
  |              ^^^^^^^^^^^^ expected `&str`, found `usize`

For more information about this error, try `rustc --explain E0308`.
error: could not compile `variables` due to previous error