今まで書いてきたプログラミング言語にはない概念だったので。
シャドーイング
let x = 0; let x = "a";
同名の変数が再宣言されたとき、前者を隠す(再宣言以降は前者は参照不可となり後者が参照される)。
let x = 0; println("{}", x); // 0 let x = "a"; println("{}", x); // a
ところでこのコード、せっかくミュータブルで不変にしているのに、シャドーイングのせいで再代入されたように見える。ミュータブルにする意義が薄れるように思うのだが……。
シャドーイングがない言語
C/C++, C#, Javaなどはコンパイルエラーになる。
他は以下。
- Shellは再代入される。(問題があっても元から文字列型のみなのでエラーにならず誤動作する)
- JavaScript, Pythonは再代入される。(型は実行時に決まる。問題があれば実行時エラーになる)
「コンパイルする言語において、静的型付けで同一スコープ内に同名変数を宣言したら、コンパイルエラーになる」ものだと思っていた。
シャドーイングの価値
同じものを意味するが型の違う変数がある。これに同じ名前をつけることができる。たとえば型名をプレフィックスとして「intVar」「strVar」などという冗長な名前にしなくてもよい。どちらも「Var」でいい。
シャドーイングの悪影響
あるとしたら何か。
意図せず上書き
まちがって別の変数であるべきものを同名の変数で再宣言してしまうことがあるかもしれない。バグの元。
シャドーイングがない言語ならコンパイルエラーになってくれる。だが、シャドーイングがあるRust言語では上書きされてしまう。これに気づくにはユニットテストが必要だろう。(おそらくデバッグで変数の確認などしないだろうから)。後戻り作業が生じてしまう。
コードリーディング
シャドーイングがあると、コードリーディングの手間が増える可能性がある。
ある特定の変数名でコードをテキスト検索すると、再代入、再宣言(シャドーイング)の2種類があり、探しているコード箇所を見つけるのに少しだけ時間がかかるかもしれない。
「変数名を流用できる」ことは名付けの手間が省ける反面、名前の一意性が下がってコードリーディングに手間取るかもしれない。トレードオフ。メンテより開発を優先か。もっとも、深刻ではないだろうが。
対象環境
- Raspbierry pi 3 Model B+
- Raspbian stretch 9.0 2018-11-13
- bash 4.4.12(1)-release
- rustc 1.34.2 (6c2484dc3 2019-05-13)
- cargo 1.34.0 (6789d8a0a 2019-04-01)
$ uname -a Linux raspberrypi 4.14.98-v7+ #1200 SMP Tue Feb 12 20:27:48 GMT 2019 armv7l GNU/Linux
前回まで
- Rustを学んでみたい(プログラミング言語)
- Rustの環境構築
- RustでHelloWorld
- Rustの和訳ドキュメント
- Cargoでプロジェクト作成・ビルド・実行
- クレートとは?
- Rustで関数を使ってみる
- Rustでモジュールを使ってみる
- Rustで乱数を生成する(rand)
- Rustで標準入力する(std::io::stdin().read_line())
- RustでMatch判定する(match)
- Rustでprintとread_lineを1行にする方法
- Rustで数当てゲーム
- クレート名にドット.が使えない
- Rustの変数と可変性(let, mut) error[E0384]: cannot assign twice to immutable variable
x
- Rustのimmutable束縛とconst定数の違い
- RustのREPL、evcxrのインストールに失敗した
- Rustでコンパイルするときの変数未使用warningを消す
- Rustの変数(再代入、再宣言(シャドーイング))