シャドウイングとは、同じスコープ内で同じ名前の変数を何度も宣言できる機能であり、新しい変数が前の変数を「隠す」ことを意味します。シャドウイングのない言語(C、C++など)では、変数を再定義することはエラーや未定義の動作を引き起こします。Rustはシャドウイングを許可し、それぞれの変数は新しい型または値を持つ独立したオブジェクトです。値の段階的変換を行う際に便利です—例えば、ストリングを数値に変換する際に新しい名前を考える必要がありません。
問題:一方では読みやすさの向上、変数名の肥大化を防止しますが、他方では、複雑なブロック内で変数を偶然「隠して」しまい、予期しない結果を得ることからデバッグが困難になります。
解決策:シャドウイングは、実際に変換を容易にし、読みやすさを損なわない場合にのみ使用されます。「let var = ...;」ごとに新しい変数が作成され、古い変数は宣言ブロックの外で変更されません。
コード例:
fn example() { let x = "42"; let x = x.parse::<i32>().unwrap(); println!("x: {}", x); // x: 42 }
主な特徴:
シャドウイングは変数のミュータビリティを変更できますか?
はい、ミュータブルでない変数をミュータブルな変数で隠すことができますし、その逆も可能です:
let x = 5; let mut x = x; x += 1;
シャドウイングは、以前の変数が破壊されたことを意味しますか?
いいえ、以前の変数の値は宣言されたブロックの最後まで生き続きますが、名前でアクセスできなくなります。
ループ内や入れ子のブロック内でシャドウイングを使用できますか?
はい、各スコープは同じ名前の変数を宣言することを許可し、これらは異なる変数です。
関数内に let result = expr1; ... let result = expr2; があり、型が異なる。
利点:
欠点:
シャドウイングは型の変更のみに使用されます:最初に文字列をパースして、その後で数値を代入します。
利点:
欠点: