Rustの変数宣言の基本と、型の扱い方を学びましょう。
1. 変数とは? 📦
プログラミングにおける変数とは、データを一時的に保存しておくための「箱」のようなものです。Rustでは、この箱に名前をつけて、様々な値(数値、文字列など)を入れておくことができます。
Rustの大きな特徴として、変数はデフォルトで不変(immutable)であるという点があります。これは、一度変数に値を入れると、後からその値を変更できないということです。これにより、意図しない値の変更を防ぎ、安全なコードを書きやすくなります。もちろん、値を変更したい場合は、変更可能(mutable)な変数として宣言することもできます。
2. 変数の宣言: let キーワード
Rustで変数を宣言するには、let
キーワードを使います。基本的な構文は以下の通りです。
fn main() {
let message = "こんにちは、Rust!"; // messageという名前の変数に文字列を束縛
let number = 100; // numberという名前の変数に整数を束縛
println!("{}", message); // 変数の値を表示
println!("数値は: {}", number); // 変数の値を表示
}
この例では、message
という名前の変数に文字列リテラル "こんにちは、Rust!"
を、number
という名前の変数に整数 100
を束縛(bind)しています。一度束縛されると、デフォルトではこれらの変数の値を変更することはできません。
3. 型推論: コンパイラにおまかせ! 🤔
先ほどの例で、変数に型を明示的に指定しませんでしたね。Rustは静的型付け言語ですが、強力な型推論(Type Inference)の機能を持っています。これは、コンパイラがコードの文脈から変数の型を自動的に判断してくれる機能です。
fn main() {
let implicit_integer = 50; // コンパイラは i32 (32ビット符号付き整数) と推論します
let implicit_float = 3.14; // コンパイラは f64 (64ビット浮動小数点数) と推論します
// 型を確認したい場合は、わざと間違った型の関数に渡してみるとエラーで教えてくれます
// takes_string(implicit_integer); // ← これはコンパイルエラーになります
}
// fn takes_string(s: String) { /* ... */ } // 例: 文字列を期待する関数
多くの場合、型推論のおかげで冗長な型指定を省略でき、コードを簡潔に保つことができます。ただし、複数の型が考えられる場合など、コンパイラが型を特定できない場合は、明示的に型を指定する必要があります。
4. 明示的な型指定: 型をはっきりさせる 🎯
型推論が便利な一方で、意図的に特定の型を使いたい場合や、コンパイラが型を推論できない場合には、明示的な型指定(Explicit Type Annotation)を行います。変数名の後にコロン :
と型名を記述します。
fn main() {
let count: i32 = 10; // 32ビット符号付き整数型を明示
let pi: f32 = 3.14159; // 32ビット浮動小数点数型を明示
let is_done: bool = false; // ブール型 (true または false) を明示
let initial: char = 'R'; // 文字型を明示
println!("カウント: {}", count);
println!("円周率 (f32): {}", pi);
println!("完了フラグ: {}", is_done);
println!("イニシャル: {}", initial);
}
Rustには様々な基本データ型(プリミティブ型)があります。代表的なものをいくつか紹介します。
分類 | 型 | 説明 | 例 |
---|---|---|---|
整数型 (Integer) |
i8 , i16 , i32 , i64 , i128 |
符号付き整数(負数を含む)。数字はビット数。デフォルトは i32 。 |
let num: i32 = -10; |
u8 , u16 , u32 , u64 , u128 |
符号なし整数(0と正数のみ)。数字はビット数。 | let age: u8 = 30; |
|
isize |
符号付きポインタサイズ整数。プログラムを実行するコンピュータのアーキテクチャ(32bit or 64bit)に依存。 | let index: isize = -5; |
|
usize |
符号なしポインタサイズ整数。コレクションのインデックスなどに使われる。 | let length: usize = 100; |
|
浮動小数点数型 (Floating-Point) |
f32 |
32ビット単精度浮動小数点数。 | let price: f32 = 99.9; |
f64 |
64ビット倍精度浮動小数点数。デフォルト。 | let pi = 3.1415926535; |
|
ブール型 (Boolean) |
bool |
true または false のどちらかの値。 |
let is_active: bool = true; |
文字型 (Character) |
char |
単一のUnicode文字。シングルクォーテーション' で囲む。 |
let grade: char = 'A'; |
数値リテラルに直接型を指定することもできます(例: 10u32
, 3.14f64
)。
5. 可変変数: 値を変更したいとき 🔄
変数の値を後から変更したい場合は、let
の後に mut
キーワードを追加して可変(mutable)変数として宣言します。
fn main() {
let mut count = 0; // 可変変数として宣言
println!("最初のカウント: {}", count);
count = count + 1; // 値を変更
println!("次のカウント: {}", count);
}
mut
をつけずに再代入しようとすると、コンパイルエラーになります。Rustは安全性を重視するため、意図しない変更を防ぐために、変更が必要な変数にのみ mut
をつけることを推奨しています。
6. シャドーイング: 同じ名前で再宣言 🎭
Rustにはシャドーイング(Shadowing)という機能があります。これは、既に存在する変数と同じ名前で、let
を使って新しい変数を宣言できる機能です。
fn main() {
let x = 5;
println!("最初のx: {}", x); // 5
let x = x + 1; // シャドーイング: 新しい変数xが古いxを覆い隠す
println!("シャドーイング後のx: {}", x); // 6
{
let x = x * 2; // 内側のスコープでさらにシャドーイング
println!("内側のスコープのx: {}", x); // 12
} // 内側のスコープの終わり。内側のxはここで消える
println!("スコープを抜けた後のx: {}", x); // 6 (外側のスコープのxが再び見える)
// 型を変えることもできる!
let spaces = " "; // 文字列型
let spaces = spaces.len(); // usize型 (文字数)
println!("スペースの数: {}", spaces); // 3
}
シャドーイングは、mut
を使った再代入とは異なります。シャドーイングでは、let
で完全に新しい変数が作られます。そのため、変数の型を変更することも可能です(上の例のspaces
のように)。これは、値を変換しつつ同じ名前を使い続けたい場合に便利です。
まとめ ✨
今回はRustの変数と型の基本について学びました。
- 変数は
let
キーワードで宣言し、デフォルトで不変です。 - Rustは強力な型推論を持ちますが、
: 型名
で明示的に型を指定することもできます。 - 値を変更したい変数は
let mut
で可変にします。 let
を使って同じ名前の変数を再宣言するシャドーイングという機能があります。
これらの基本をしっかり押さえて、次のステップに進みましょう!🚀
コメント