この記事は、2023年7月に作成したものです。
はじめに
以前から興味があったRustを、日本語のドキュメントをもとに、学習を始めました!
自分の考えをまとめるために、記事を書いていこうと思います。
今回は、日本語ドキュメント3.1についてまとめていきます!
この記事でできること
Rustでの変数宣言や変数の仕組みを学習できます。
環境
-
- macOS Monterey == 12.5
-
- Docker == 23.0.5
-
- Rust == 1.70.0
- Cargo == 1.70.0
変数の宣言方法
Rustの変数宣言ではletを使用します。
let x = 5;
xという変数を宣言して5を代入できました。
Rustの変数の特徴
Rustでは、変数の型を注釈しなくても、型推論によって適切な型を割り振ってくれます。
ちょうど、PythonやSwiftなどと同じですね!
(※型については、次回の記事で詳しく解説しようと思います。)
また、Rustの変数は不変変数といい、何も指定しない場合値を変更することができない変数が定義されます。
let x = 5;
...
x = 6 // error[cannot assign twice to immutable variable]
これがややこしい!!
「変数なのに変更できないなんて…」「定数と変わらないじゃないか!」などと思うでしょう。
私もそう思いました。
この仕組みの恩恵を受けるためには、もっとRustの経験を積まないといけませんね…
一方で、変数の値を変更できないことによって、不便なシチュエーションも多くあります。
そこで、変数宣言時にmutをつけることにより、他の言語と同じ振る舞いをする可変変数を宣言することができます。
let mut y = 5;
...
y = 6; // エラーは出ない
シャドーイング
Rustの変数にはシャドーイングというものがあります。
シャドーイングとは、以前に定義した変数を再定義することです。この際、新しい変数は前の変数を覆い隠します
let x = 5;
println!(x) // 5
let x = x + 2
println(x) // 7
また、別のスコープでシャドーイングされた際、そのスコープを抜けると元の値に戻ります。
let x = 5;
println!(x) // 5
{
let x = "シャドーイングされています";
println!(x) // シャドーイングされています
}
println!(x) // 5
シャドーイングでは、上のプログラムのように変数の型が変わることが許容されています。
そのため、型ごとに変数を定義する必要がなく、変数名を使い回して開発することができます。
これはシャドーイングのメリットと言えるでしょう。
私はRustでの開発経験が浅いため、なんとなく便利そう! というイメージしか今のところないです。
変数と定数
Rustの変数はデフォルトでは不変変数である。これを聞いて「定数と何が違う?」と思った方も多いでしょう。
私もそのうちの1人です。
ですが、もちろんRustでは変数と定数の区別がしっかりとあります。
コメントより
「変数と定数の本質的な違いはいつ値が決定されるか」
ということでした!
補足ありがとうござます!
定数はコンパイル時つまり、cargo buildを実行し、実行可能ファイルが生成される時点で決定されます。
それに対し変数はランタイム時つまり、実行可能ファイルを実行した時に決定されます。
定数は実行される前から、既に確定している存在だそうです!
では、定数では制限されている書き方を見てみましょう。
型注釈の省略ができない
定数を定義する際は必ず型注釈を行う必要があります。
// 定数は「const」を使用します
const DAY_HOUR: u16 = 24 // 整数型の定数を定義
const DAY_MINUTE = 14400 // 型注釈がないためエラー
同スコープ内でのシャドーイングができない
変数は、同スコープ内でもシャドーイングできるのに対し、定数は同スコープ内ではシャドーイングができません。
同スコープ内でシャドーイングしてしまうと、定数の不変が保証されなくなるためです。
しかし、別のスコープであればシャドーイングが可能です。
const MAX_NUMBER: u32 = 100_000;
println!(MAX_NUMBER); // 100000
const MAX_NUMBER: u32 = 200_000; // error:定数MAX_NUMBRERは定義されているためエラー
{
const MAX_NUMBER: u32 = 200_000;
println!(MAX_NUMBER); // 2000000 スコープが違うためエラーはでない
}
println!(MAX_NUMBER) // 100000 シャドーイングから解放されたので元に戻る
まとめ
だいぶ複雑になってきました…
変数で大事なことは以下の通りです。
-
- 定義する時にはletを使用する
-
- 変数はデフォルトでは不変変数となる
-
- 可変変数を定義するためにはmutを使用する
シャドーイングによって変数を覆い隠すことができる
定数と変数は別物
自分なりにまとめていて、解釈が甘いところがありそうなので、コメントなどで意見お願いします!
参考文献
The Rust Programming Lamguage 日本語版