Rustでは、変数のスコープはブロック(階段状の波かっこ{})によって制限されます。同じ名前の新しい変数を現在のスコープまたは外部スコープで既存のものと再宣言することをシャドウイング("影を作る")と呼びます。シャドウイングを使用すると、変数の型と値を変更でき、イミュータビリティの概念を破ることなく行うことができます。
例:
let x = 5; // x: i32 = 5 let x = x + 1; // x: i32 = 6 (古いxをシャドウイング) let x = "hello"; // x: &str = "hello" (型が変更された)
シャドウイングはパフォーマンスに影響を与えません(これは純粋に構文的な構造であり、LLVM IRレベルで異なる変数にコンパイルされます)が、コードの可読性と保守性を著しく低下させ、論理的なエラーのリスクを高める可能性があります。
質問: 変数がシャドウイングされると、以前の変数がメモリの所有権を持っていた場合(例えば、String)、リソースは解放されますか?
多くの人が回答する: いいえ、変数は単に「再定義」されるだけだから。
正しい答え: はい、変数がシャドウイングされると、古い値はスコープから外れ、リソースを所有していた場合はDropが呼び出されます。これは、メモリの正しい解放を保証します。
例:
let s = String::from("abc"); let s = 5; // ここでStringが解放される(Dropが呼び出される)
物語
若い開発者がオープンファイルディスクリプタを持つ構造体でシャドウイングを使用し、予期せず早く変数をシャドウイングしたため、ファイルの操作が終了する前に誤ってファイルを閉じてしまい、データ損失を引き起こしました。
物語
ある研究プロジェクトで、同じネストレベルの変数にシャドウイングが適用され、そのために開発者たちはしばしば混乱し、「古い」変数の値が現在有効だと思い込んでいました。
物語
大規模なサーバーアプリケーションにおいて、構造体のフィールドとメソッド内の変数の暗黙的なシャドウイングが明白でないエラーを引き起こし、フィールドは変更されず、同じ名前の新しいローカル変数が変更されました。このエラーは、システムの不正な動作の原因を長い間探した後に発見されました。