my.code(); Logomy.code();
Rust-1.基本構文と「不変性」

my.code(); Logomy.code();

  • C++
    • 0.C++の世界へようこそ
    • 1.型システムと制御構造
    • 2.データ集合とモダンな操作
    • 3.ポインタとメモリ管理
    • 4.関数と参照渡し
    • 5.プロジェクトの分割とビルド
    • 6.クラスの基礎
    • 7.クラスを使いこなす
    • 8.継承とポリモーフィズム
    • 9.テンプレート
    • 10.STL ①:コンテナ
    • 11.STL ②:アルゴリズムとラムダ式
    • 12.RAIIとスマートポインタ
  • JavaScript
    • 0.JavaScriptへようこそ
    • 1.基本構文とデータ型
    • 2.制御構文
    • 3.関数とクロージャ
    • 4.'this'の正体
    • 5.オブジェクトとプロトタイプ
    • 6.クラス構文
    • 7.配列とイテレーション
    • 8.非同期処理①: Promise
    • 9.非同期処理②: Async/Await
  • Python
    • 0.環境構築と基本思想
    • 1.基本構文とデータ型
    • 2.リスト、タプル、辞書、セット
    • 3.制御構文と関数
    • 4.モジュールとパッケージ
    • 5.オブジェクト指向プログラミング
    • 6.ファイルの入出力とコンテキストマネージャ
    • 7.例外処理
    • 8.ジェネレータとデコレータ
  • Ruby
    • 0.rubyの世界へようこそ
    • 1.基本構文とデータ型
    • 2.制御構造とメソッド定義
    • 3.すべてがオブジェクト
    • 4.コレクション (Array, Hash, Range)
    • 5.ブロックとイテレータ
    • 6.クラスとオブジェクト
    • 7.モジュールとMix-in
    • 8.Proc, Lambda, クロージャ
    • 9.標準ライブラリの活用
    • 10.テスト文化入門
    • 11.メタプログラミング入門
  • Rust
    • 0.Rustの世界へようこそ
    • 1.基本構文と「不変性」
    • 2.関数と制御フロー
    • 3.所有権
    • 4.借用とスライス
    • 5.構造体とメソッド構文
    • 6.列挙型とパターンマッチ
    • 7.モジュールシステムとパッケージ管理
    • 8.コレクションと文字列
    • 9.エラーハンドリング
    • 10.ジェネリクスとトレイト
    • 11.ライフタイム
  • TypeScript
    • 0.TypeScriptへようこそ
    • 1.基本的な型と型推論
    • 2.オブジェクト、インターフェース、型エイリアス
    • 3.関数の型定義
    • 4.型を組み合わせる
    • 5.ジェネリクス
    • 6.クラスとアクセス修飾子
    • 7.非同期処理とユーティリティ型
my.code(); Logomy.code();

環境構築不要、その場で実践。

ut-code / my-code

Copyright © 2026 ut.code();

my.code(); について
コード実行環境についてAI質問機能についてライセンスお問い合わせ
ut.code(); について
公式ウェブサイト公式 𝕏 アカウント

第1章: 基本構文と「不変性」の哲学

他の言語での開発経験がある方にとって、Rustの学習で最初に直面するカルチャーショックが「変数の扱い」です。

C++やJava、Pythonなどでは「変数はデフォルトで書き換え可能(Mutable)」であることが一般的ですが、Rustでは「デフォルトで不変(Immutable)」です。この設計こそが、Rustがコンパイル時に多くのバグを排除できる理由の根幹にあります。

第2章では、Rustの構文の基礎と、その背後にある哲学を学びます。

変数と可変性(let vs let mut)

Rustでは変数を宣言するために let キーワードを使用します。しかし、単に let で宣言された変数は、値を一度代入すると二度と変更できません。

不変変数(Immutable)

まず、以下のコードを見てください。これは意図的にコンパイルエラーになるように書かれています。

ファイルを編集:immutability_error.rs
fn main() {
    let x = 5;
    println!("xの値は: {}", x);
    
    // 値を再代入しようとする(コンパイルエラーになる)
    x = 6; 
    println!("xの値は: {}", x);
}
ブラウザ上で動作するrustの実行環境です。
左上の実行ボタンを押して、このページ内のimmutability_error.rsに書かれている内容を実行します。
error[E0384]: cannot assign twice to immutable variable `x`
 --> immutability_error.rs:6:5
  |
2 |     let x = 5;
  |         - first assignment to `x`
...
6 |     x = 6; 
  |     ^^^^^ cannot assign twice to immutable variable
  |

これをコンパイルしようとすると、Rustコンパイラは「不変変数 x に二度代入することはできない」と強く叱ってくれます。

可変変数(Mutable)

値を変更したい場合は、mut(mutableの略)キーワードを明示的に付ける必要があります。これにより、「この変数は値が変わる可能性がある」とコードの読み手やコンパイラに宣言します。

ファイルを編集:mutability_demo.rs
fn main() {
    // mut をつけることで可変になる
    let mut x = 5;
    println!("xの値は: {}", x);
    
    x = 6;
    println!("xの値は: {}", x);
}
ブラウザ上で動作するrustの実行環境です。
左上の実行ボタンを押して、このページ内のmutability_demo.rsに書かれている内容を実行します。
xの値は: 5
xの値は: 6

なぜデフォルトが不変なのか? 大規模なシステムや並行処理において、「いつの間にか値が変わっている」ことはバグの主要な原因です。Rustは「変更が必要な箇所だけを明示的にする」ことで、コードの予測可能性と安全性を高めています。

シャドーイング(Shadowing)

Rustには、他の言語ではあまり見られないシャドーイング(Shadowing)という強力な機能があります。これは、同じ名前の変数を let を使って再宣言することで、前の変数を「覆い隠す」機能です。

mut との違いは2点あります:

  1. 型を変更できる: mut は値の変更しかできませんが、シャドーイングは新しい変数を宣言しているのと同じなので、型を変えることができます。
  2. 不変に戻る: 処理が終わった後、その変数は再び不変(immutable)になります。
ファイルを編集:shadowing.rs
fn main() {
    let x = 5;
    
    // 最初のシャドーイング: 値を加工する
    let x = x + 1;

    {
        // 内側のスコープでのシャドーイング
        let x = x * 2;
        println!("内側のスコープでのx: {}", x);
    }

    // スコープを抜けると、外側のxの値が参照される
    println!("外側のスコープでのx: {}", x);

    // 型の変更を伴うシャドーイングの例
    let spaces = "   "; // 文字列スライス型
    let spaces = spaces.len(); // usize型(整数)
    
    println!("スペースの数: {}", spaces);
}
ブラウザ上で動作するrustの実行環境です。
左上の実行ボタンを押して、このページ内のshadowing.rsに書かれている内容を実行します。
内側のスコープでのx: 12
外側のスコープでのx: 6
スペースの数: 3

他言語では spaces_str、spaces_num のように変数名を変える場面でも、Rustでは変数の意味が変わらなければ同じ名前を再利用してコードをすっきり保つことができます。

基本的なデータ型

Rustは静的型付け言語ですが、型推論が強力なため、多くの場合に型注釈は不要です。しかし、ここでは明示的な理解のために型を見ていきます。

スカラー型(単一の値を表す)

  1. 整数型:
    • i32 (デフォルト), i64, u32, u8 など。
    • アーキテクチャ依存の isize, usize (インデックス用によく使われる)。
  2. 浮動小数点型:
    • f64 (デフォルト, 倍精度), f32 (単精度)。
  3. 論理値型:
    • bool (true / false)。
  4. 文字型:
    • char。Rustのcharは4バイトで、Unicodeスカラー値を扱います(ASCIIだけでなく、漢字や絵文字も1文字として扱えます)。シングルクォート ' で囲みます。

複合型(複数の値をまとめる)

  1. タプル (Tuple):
    • 異なる型をまとめる固定長のリストです。
  2. 配列 (Array):
    • 同じ型の要素をまとめる固定長のリストです。
    • ※ 長さが可変のリストが必要な場合は、後の章で学ぶ「ベクタ (Vec)」を使います。配列はスタック上に確保されるため、高速ですがサイズ変更はできません。
ファイルを編集:data_types.rs
fn main() {
    // --- スカラー型 ---
    let int_val: i32 = -10;
    let float_val: f64 = 2.5;
    let char_val: char = 'あ'; // Unicode文字
    let emoji: char = '🦀';

    println!("Scalar: {}, {}, {}, {}", int_val, float_val, char_val, emoji);

    // --- 複合型: タプル ---
    // 型が異なっていてもOK
    let tup: (i32, f64, u8) = (500, 6.4, 1);
    
    // 分解(Destructuring)して値を取り出す
    let (x, y, z) = tup;
    println!("Tuple分解: yの値は {}", y);

    // ドット記法でアクセス
    println!("Tupleアクセス: 最初の値は {}", tup.0);

    // --- 複合型: 配列 ---
    // 型と長さを指定: [型; 長さ]
    let arr: [i32; 5] = [1, 2, 3, 4, 5];
    
    // 同じ値で初期化する記法 let a = [3; 5] は [3, 3, 3, 3, 3]
    let months = ["Jan", "Feb", "Mar"];
    
    println!("Array: 2番目の月は {}", months[1]);
}
ブラウザ上で動作するrustの実行環境です。
左上の実行ボタンを押して、このページ内のdata_types.rsに書かれている内容を実行します。
Scalar: -10, 2.5, あ, 🦀
Tuple分解: yの値は 6.4
Tupleアクセス: 最初の値は 500
Array: 2番目の月は Feb

この章のまとめ

  • 不変性がデフォルト: 変数は mut をつけない限り変更できない。これにより安全性が担保される。
  • シャドーイング: let を重ねることで変数の再定義が可能。値の加工や型の変更に便利。
  • データ型: 整数、浮動小数点、文字(Unicode対応)、タプル、配列(固定長)などの基本型がある。

他の言語では「定数」として扱われるような使い方が、Rustでは「デフォルトの変数」になります。最初は窮屈に感じるかもしれませんが、「変化するものは目立つようにする」というRustの哲学に慣れると、コードの流れが追いやすくなることに気づくはずです。

練習問題 1: 計算とシャドーイング

以下の手順に従ってコードを書いてください。

  1. 変数 x を定義し、文字列 "100" を代入する。
  2. シャドーイングを使って、x を数値の 100 (文字列からパースする)に変換する。
    • ヒント: "100".parse().expect("Not a number") で数値に変換できます。
  3. さらにシャドーイングを使って、x に 50 を足した値にする。
  4. 最終的な x の値を表示する。
ファイルを編集:practice2_1.rs
ブラウザ上で動作するrustの実行環境です。
左上の実行ボタンを押して、このページ内のpractice2_1.rsに書かれている内容を実行します。

練習問題 2: 配列とタプルの操作

  1. 浮動小数点型の配列 data を定義し、[1.1, 2.2, 3.3] で初期化する。
  2. タプル result を定義し、配列 data の最初の要素と最後の要素を格納する。
  3. タプルを分解(デストラクチャリング)して、それぞれの値を表示する。
  4. この一連の操作で mut が必要ない理由を考える。
ファイルを編集:practice2_2.rs
ブラウザ上で動作するrustの実行環境です。
左上の実行ボタンを押して、このページ内のpractice2_2.rsに書かれている内容を実行します。
前のページ« Rustの世界へようこそ
次のページ関数と制御フロー »