[Rustのはじめ方] Part5: 変数と型(型推論・明示的型指定)

Rust

Rustの変数宣言の基本と、型の扱い方を学びましょう。


プログラミングにおける変数とは、データを一時的に保存しておくための「箱」のようなものです。Rustでは、この箱に名前をつけて、様々な値(数値、文字列など)を入れておくことができます。

Rustの大きな特徴として、変数はデフォルトで不変(immutable)であるという点があります。これは、一度変数に値を入れると、後からその値を変更できないということです。これにより、意図しない値の変更を防ぎ、安全なコードを書きやすくなります。もちろん、値を変更したい場合は、変更可能(mutable)な変数として宣言することもできます。

Rustで変数を宣言するには、let キーワードを使います。基本的な構文は以下の通りです。


fn main() {
    let message = "こんにちは、Rust!"; // messageという名前の変数に文字列を束縛
    let number = 100; // numberという名前の変数に整数を束縛

    println!("{}", message); // 変数の値を表示
    println!("数値は: {}", number); // 変数の値を表示
}
        

この例では、message という名前の変数に文字列リテラル "こんにちは、Rust!" を、number という名前の変数に整数 100 を束縛(bind)しています。一度束縛されると、デフォルトではこれらの変数の値を変更することはできません。

先ほどの例で、変数に型を明示的に指定しませんでしたね。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) { /* ... */ } // 例: 文字列を期待する関数
        

多くの場合、型推論のおかげで冗長な型指定を省略でき、コードを簡潔に保つことができます。ただし、複数の型が考えられる場合など、コンパイラが型を特定できない場合は、明示的に型を指定する必要があります。

型推論が便利な一方で、意図的に特定の型を使いたい場合や、コンパイラが型を推論できない場合には、明示的な型指定(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)。

変数の値を後から変更したい場合は、let の後に mut キーワードを追加して可変(mutable)変数として宣言します。


fn main() {
    let mut count = 0; // 可変変数として宣言
    println!("最初のカウント: {}", count);

    count = count + 1; // 値を変更
    println!("次のカウント: {}", count);
}
        

mut をつけずに再代入しようとすると、コンパイルエラーになります。Rustは安全性を重視するため、意図しない変更を防ぐために、変更が必要な変数にのみ mut をつけることを推奨しています。

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 を使って同じ名前の変数を再宣言するシャドーイングという機能があります。

これらの基本をしっかり押さえて、次のステップに進みましょう!🚀

コメント

タイトルとURLをコピーしました