Rust学習ガイド
カテゴリ別に整理されたRustプログラミングガイド
📖 基礎文法
所有権と借用 — RustがGCなしでメモリを管理する仕組み
コンパイル時にメモリ安全性を保証するRustの核心ルール
Rustの所有権システムはGCなしでメモリ安全性を保証する。値1つに所有者1つ、借用時は読み取り専用複数または書き込み専用1つのみ許可。
ライフタイム — Rustコンパイラが参照の有効範囲を追跡する仕組み
'aが何かを一発で理解する
ライフタイムは参照が有効な範囲をコンパイラに伝える注釈だ。大半の場合省略(elision)可能だが、複数の参照が絡む時は明示的に書く必要がある。
パターンマッチング — matchとif letで分岐する
switch/caseの上位互換、Rustコードの核心表現方式
Rustのmatchは値を分解しながら同時に分岐する。全ケースを漏れなく処理する(exhaustive)コンパイラ強制のおかげで、漏れのない分岐が保証される。
Resultと?演算子 — Rustのエラー処理パターン
try-catchなしでエラーを型で扱う方法
Rustには例外(exception)がない。代わりにResult<T, E>型で成功/失敗を明示し、?演算子でエラーを簡潔に伝搬する。
🧬 型システム
トレイトとジェネリクス — Rustの多態性
インターフェース+ジェネリクスが合わさったRustの抽象化ツール
トレイトはJavaのインターフェースに似ているがより強力だ。ジェネリクスと組み合わせるとコンパイル時に型が確定する(monomorphization)ゼロコスト抽象化が可能。
Enum、Option、Result — Rustの代数的データ型
nullのない世界を作る型システム
Rustにはnullがない。Option<T>が値の不在を、Result<T, E>が演算の失敗を型で表現する。enumがデータを持てるから可能な設計だ。
Box、Rc、Arc、RefCell — スマートポインタガイド
所有権ルールを柔軟に回避するツール
所有権ルールだけでは解決できないパターン(再帰型、共有所有権、内部可変性)がある。スマートポインタがこのギャップを埋める。
⚡ 並行処理
🔧 実践パターン
Rustで作れるもの — 初級から上級までのプロジェクトロードマップ
Hello Worldの次に何を作ればいいかわからない時
Rustの文法は覚えたけど何を作ればいいかわからないなら。難易度別に実際に作れるプロジェクトを整理した。CLIツールからWebサーバー、ゲームエンジンまで。
RustでCLIツールを作る
clap + serdeで素早く作る実践コマンドラインツール
RustはCLIツール制作に特に強い。シングルバイナリにコンパイルされ、起動時間が速く、clap/serdeエコシステムが堅実。
Rust → WASM — ブラウザでRustを動かす
wasm-pack + wasm-bindgenでJSからRust関数を呼ぶ
WASMターゲットにコンパイルすればRustがブラウザでネイティブ速度で実行される。wasm-bindgenがJS↔Rust間の型変換を自動処理。
FFI — RustからCライブラリを呼ぶ
extern "C"、bindgen、unsafeの実践的使い方
RustはC ABIと直接互換。extern "C"ブロックでC関数を宣言しunsafeで呼び出す。VOICEVOX EngineがCoreをctypesで呼ぶのはこのパターンの逆方向(Rust→C ABI公開)。
💎 Rubyist向けRust
変数と不変性 — Rubyの自由な再代入が消えた理由
let, mut, shadowing, const — Ruby変数と1:1比較
Rubyでは変数はいつでも再代入できる。Rustはデフォルトが不変。mut、shadowing、constの違いをRubyコードと比較して整理した。
型システム — 動的型付けの自由を手放して得るもの
Rubyのダックタイピング vs Rustの静的型推論
Rubyはダックタイピング。「quackすればアヒル」。Rustはコンパイル時に全ての型を決定する。推論が強力なので大抵は書く必要はないが、一度決まったら絶対に変わらない。
関数とメソッド — defがfnになると何が変わるか
戻り値の型、セミコロン、そしてRubyと同じ「最後の式が戻り値」ルール
Rubyのdef → Rustのfn。引数の型と戻り値の型を明示する必要があり、セミコロン1つで戻り値の有無が決まる。それ以外はRubyと意外と似ている。
構造体とimpl — Rubyのclassが2つに分かれる
structでデータ、implでメソッド、traitで多態性
Rubyのclassはデータとメソッドを1箇所にまとめる。Rustはstruct(データ)とimpl(メソッド)に分離し、継承の代わりにtraitで共通の振る舞いを定義する。
Enumとパターンマッチング — Symbolとcase/whenの強力な進化版
Rustのenumはデータを持てる — Rubyにはない概念
RubyのSymbolや定数グループに相当するRustのenumは、各バリアントにデータを持てる。matchはcase/whenの強化版で、全ケースを漏れなく処理する必要がある。
Option<T> — nilが消えた世界で生き残る
Rubyのnilと&.演算子がRustでどう変わるか
Rubyのnilはどこからでも出てくる。Rustにはnilがない。値が存在しないかもしれない場合はOption<T>を使い、コンパイラがNone処理を強制する。
Resultとエラー処理 — begin/rescueが消えた場所
例外の代わりに戻り値でエラーを処理するRustの方式
Rubyは例外を投げてrescueで捕まえる。Rustには例外がない。代わりにResult<T, E>を返し、?演算子でエラーを伝播する。
イテレータとクロージャ — Rubyistが最も親しみを感じる領域
select/map/reduceがfilter/map/foldに変わっただけ
RubyのEnumerableメソッドがほぼそのままRustにある。名前が少し違うだけでチェーンパターンも同じ。RubyistがRustで最も速く適応する部分。
String vs &str — Rubyにはない文字列の二つの顔
所有する文字列と借用する文字列の違い
Rubyの文字列はString1つ。Rustには2種類ある:String(所有)と&str(借用)。最初は混乱するが、所有権の概念と繋がる核心。
コレクション — ArrayとHashがVecとHashMapになると
型が固定された世界の配列とハッシュマップ
RubyのArrayとHashがRustではVec<T>とHashMap<K, V>になる。最大の違いは1つの型しか入らないこと。
所有権 — RubyのGCがやってくれていたことを自分でやる
Rubyistが最も苦戦するRustの核心概念
RubyではGCがメモリを片付けてくれる。Rustでは所有権ルールがGCの代わりをする。値を渡すと元が消えるmoveの概念が核心。
Cargo — BundlerとRakeが1つになったもの
Gemfile → Cargo.toml、bundle exec → cargo run
Ruby生態系ではBundler(依存性)とRake(ビルド/タスク)を別々に使うが、RustはCargo1つで全部やる。プロジェクト生成、ビルド、テスト、依存性管理、配布まで。