Rust - Basic - 01 - Variables shadowing

変数のシャドーイング

理解

Rust では、ある変数( let または let mut ) a を後続の箇で宣言することがあります。この動作をシャドーイング(shadowing)と呼びます。

  • const 定数はシャドーイングできない
  • シャドーイングにはブロック( {} )スコープを設定できる
  • シャドーイングでは、同じ変数名を使いながら新しいデータ型を同時に宣言できる

参照元

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);
}

このプログラムでは、まず x に 5 という値を束縛します。次に let x = を繰り返して x をシャドーイングし、元の値に 1 を加えるため、x の値は 6 になります。その後、側のスコープで 3 つ目の let 文がび x をシャドーイングし、直前の値に 2 を掛けることで x の値を 12 にします。そのスコープを抜けると、側でのシャドーイングは終了し、x は 6 に戻ります。このプログラムを実行すると、次のように出力されます。


$ 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

シャドーイングは、変数に mut を付けることとは異なります。let キーワードを使わずにこの変数へ代入しようとすると、コンパイル時エラーになるためです。let を使えば、値に対していくつかの変換を行ったうえで、その変換が完了した後の変数を不変にできます。

mut とシャドーイングのもう一つの違いは、let キーワードをび使うと実質的に新しい変数を作成するため、同じ名前を利しながら値の型を変できることです。たとえば、プログラムがユーザーに、文字列の間に何個のスペースを入れたいかをスペース文字で入力してもらうとします。しかし、実際にはその入力を数値として保存したい場合を考えます。


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

この構文が許されるのは、最初の spaces 変数が文字列型で、2 つ目の spaces 変数が最初の変数と同じ名前を持つ新しい変数であり、数値型だからです。これにより、spaces_str や spaces_num のような別の名前を考える必要がなくなり、より簡単な spaces という名前を利できます。一方、ここで示すように mut を使おうとすると、コンパイル時エラーになります。


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

エラーは、変数の型を変できないことを示しています。


$ 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