Rust学習記録:変数、定数、シャドーイング…基本を徹底解説!
こんにちは!今日は、Rustの学習記録をまとめていきます。
今まで、Rustをさらっと触ってはいたのですが、今回は腰を据えて、
The Rust Programming Language 日本語版
を読みながら、じっくり学習を進めています。
この記事では、Rustの基本中の基本である、
cargo
コマンドの使い方- 変数と可変性
- 定数
- シャドーイング
について、学んだことを整理していきます。「どこまで読み進めたか」という進捗記録も兼ねていますので、Rust初心者の方の参考になれば幸いです。
超便利!cargo
コマンドを使いこなそう
Rustの学習を始めてから、特に意識せず cargo
を使っていましたが、改めて調べてみると、非常に便利なツールであることが分かりました。
cargo
は、Rustのビルドシステム兼パッケージマネージャです。Rustで開発を行う上で、ほぼ必須のツールと言えるでしょう。
覚えておきたい基本的な cargo
コマンドは以下の通りです。
cargo new
: 新しいプロジェクトを作成cargo build
: プロジェクトをビルドcargo run
: プロジェクトのビルドと実行を1ステップで実行cargo check
: バイナリを生成せずにプロジェクトをビルドし、エラーがないか確認cargo update
: プロジェクトの依存関係を更新
cargo
は、ビルドの成果物を target/debug
ディレクトリに格納します。
(Windows, Linux, macOS でコマンドが共通なのは、地味に嬉しいポイントですね!)
リリースビルド
cargo build
には、--release
オプションを付けることで、最適化されたリリースビルドを作成できます。
cargo build
: 開発用ビルド (target/debug
)cargo build --release
: リリース用ビルド (target/release
)
リリースビルドは、コンパイル時間は長くなりますが、実行速度が向上します。
Rustの変数と可変性:let
と mut
Rustの変数は、デフォルトで不変 (immutable) です。
これは、一度変数に値を束縛したら、後から変更できない、ということです。
変数を作成するには、let
キーワードを使用します。
let x = 5; // x は不変 (immutable)
変数を可変 (mutable) にするには、mut
キーワードを追加します。
let mut y = 5; // y は可変 (mutable)
y = 6; // OK
不変な変数に再代入しようとすると、コンパイルエラーになります。
let x = 5;
x = 6; // コンパイルエラー: cannot assign twice to immutable variable `x`
Rustがデフォルトで変数を不変にしているのは、安全性と並行性を高めるためです。
コンパイラが「この変数の値は変わらない」と保証してくれるので、安心してコードを書くことができます。
Rustの定数:const
Rustには、変数とは別に、定数 (constants) があります。
定数は、
mut
キーワードを使用できない (常に不変)- 必ず型注釈が必要
- グローバルスコープを含む、任意のスコープで定義可能
- 定数式にしかセットできない (関数の呼び出し結果や、実行時に評価される値は不可)
といった特徴があります。
const MAX_POINTS: u32 = 100_000; // 定数 (型注釈は必須)
定数式とはコンパイル時に計算できる値です。
定数はプログラムの実行期間中、定義されたスコープ内でずっと有効です。
定数を適切に使用すると、コードの可読性が向上し、将来的な変更にも強くなります。
定数定義時に数値リテラル内にアンダースコアを挿入できる機能は数値の可読性を高めるために導入されています。
const MAX_POINTS: u32 = 100_000;
↓
const MAX_POINTS: u32 = 100000;
上記は同じ意味として扱われます。
Rustのシャドーイング:変数を「覆い隠す」
Rustには、シャドーイング (shadowing) という面白い機能があります。
シャドーイングとは、前に定義した変数と同じ名前の変数を、let
キーワードを使って再宣言することです。
これにより、新しい変数が古い変数を「覆い隠し」、以降はその名前で新しい変数を参照できるようになります。
fn main() {
let x = 5; // x は i32 型
let x = x + 1; // x をシャドーイング (i32 型)
let x = x * 2; // x をシャドーイング (i32 型)
println!("The value of x is: {}", x); // 12
let spaces = " "; // spaces は &str 型
let spaces = spaces.len(); // spaces をシャドーイング (usize 型)
println!("spacesの長さ: {}", spaces); // 3
}
シャドーイングは、mut
とは異なり、
- 変数の型を変更できる
- 実質的に新しい変数を作成する
という特徴があります。
// シャドーイングの例
fn main() {
let message = "Hello, world!"; // message は &str 型
println!("最初の message: {}", message);
let message = 12345; // message をシャドーイング、i32 型
println!("シャドーイング後の message: {}", message);
}
let message = "Hello, world!";
: message という変数を宣言し、文字列リテラル “Hello, world!” を代入しています。この時点での message の型は &str(文字列スライス)です。
let message = 12345;
: これは、以前の message をシャドーイングして、新しい message 変数を宣言し、整数値 12345 を代入しています。以前の message の型 (&str) に関係なく、新しい message は整数型 (i32) になります。
// ミュータブル変数の例
fn main() {
let mut greeting = "Hello"; // greeting は mut な &str 型
println!("最初の greeting: {}", greeting);
greeting = "Hi"; // greeting を同じ &str 型で更新
println!("更新後の greeting: {}", greeting);
}
let mut greeting = "Hello";
: greeting というミュータブルな変数を宣言し、文字列リテラル “Hello” を代入しています。この時点での greeting の型は &str です。
greeting = "Hi";
: これは、greeting が mut で宣言されており、かつ “Hi” が “Hello” と同じ型 (&str) を持つ場合に有効です。型が一致しているので、greeting の値を “Hi” で更新できます。
// ミュータブル変数と型の不一致の例
fn main() {
let mut count = "five"; // count は mut な &str 型
println!("最初の count: {}", count);
count = 5; // コンパイルエラー!count の型は &str, 5 は i32
println!("更新後の count: {}", count);
}
let mut count = "five";
: count というミュータブルな変数を宣言し、文字列リテラル “five” を代入しています。この時点での count の型は &str です。
count = 5;
: これは、count が mut で宣言されていても、5(整数型)を代入しようとすると、count の型 (&str) と 5 の型 (i32) が一致しないため、コンパイルエラーになります。
ポイント
シャドーイングでは、let
キーワードを使って新しい変数を宣言するため、古い変数の型に関係なく、新しい変数の型を自由に設定できます。
mut
キーワードを使う場合は、変数の型は最初に宣言された時点で固定され、後から変更することはできません。mut
を使用した場合変数の型のあった値のみ再代入が可能です。
今回の学習を終えて
今回は、The Rust Programming Language 日本語版を読み進めながら、
cargo
コマンド- 変数と可変性 (
let
,mut
) - 定数 (
const
) - シャドーイング
について学びました。次はデータ型について学習を進める予定です。
静的型付け言語は、覚えることが多くて大変ですが、コンパイラが型チェックをしてくれるおかげで、実行時エラーを減らせるというメリットがあります。
Rustの厳格な型システムは、安全なコードを書く上で非常に重要だと感じています。
今回も、AI (主にGemini) に助けてもらいながら学習を進めることができました。ありがとうAI!