Rust
Rustのletとconstはどう違うのか
Rustの変数はデフォルトでイミュータブル(不変)だ。
なので「immutable variable」なわけで日本語にすると「不変変数」という、言葉として崩壊しているんじゃないかと思うようなモノになる。
値が書き換えられない、ということはそれは「定数」なのでは?と思うのだが、Rustにはちゃんと定数も用意してある。
じゃあその2つはどう違うの?となるわけなんだけど、ちゃんと違うらしい。
不変変数 = 宣言だけの記述が可能。この場合1回のみ代入可能。同じ不変変数を何度宣言してもエラーにならない。
定数 = 宣言だけではエラーになる。宣言と同時に定義しなくてはならない。同じ定数を2回以上定義できない。
不変変数
let x: i32; // ← 宣言だけでもOK
x = 100; // ← 1回目は代入できる
x = 110; // ← 2回目以降はエラーになる
let x: i32; // ← 同じ不変変数をもう一度宣言してもコンパイルが通る(ただし上の x にはアクセスできなくなる)
x = 130; // ← 再宣言後、1回目は代入できる
x = 140; // ← エラーになる
定数
const C: i32; // ← エラーになる
C = 100; // ← エラーになる
const C: i32 = 100; // ← こう書く必要がある
const C: i32 = 110; // ← 2回目以降はエラーになる
Rustは同一スコープ内でも変数の再宣言が可能という言語だ。(CやC++では不可能だが、再宣言可能という言語仕様は別段珍しいわけではない)
同一スコープ内で同名の変数を再宣言するとその行以降、それまでの同名変数はシャドーイングされて見えなくなってしまい、これを再び見えるようにすることは不可能になる。
再宣言したからといって値が上書きされるわけではなく、Rust内では別々の変数として生きている。
要は宣言した数だけスタックに積まれるわけだ。(といってもループ内で宣言したからといってどんどんスタックに積まれていくわけではない。スタックの確保はそのブロックの先頭で行われる)
これは mut を付けた変数でも同様なので、意図せずうっかり再宣言してしまうとバグの要因になりうる上に、スコープアウトするまでの間はスタック領域の無駄遣いになる。
ちなみに定数はスタックに積まれない。
CやC++だと、defineした場合はプリプロセッサがコンパイル前に展開するだけなのでコンパイル後のマシンコード内にそのまま残るが、constを記述した場合は変数同様スタックに積まれる。(いわゆるイミュータブル変数になる)
Rustの定数はスタックではない場所にスタティックな状態でプログラム終了時まで生存し続けるらしい。(静的領域だと思うのだが確かなことはよく分からん。マクロではないのでコード内に直接展開されることはないはず)
|