Contents
1. Rust が注目される背景(2023 年版)
| 項目 | 内容 |
|---|---|
| メモリ安全性 | 所有権・借用・ライフタイムというコンパイル時チェックにより、ヒープ管理やデータ競合を根本的に防止。公式サイトは「no runtime or garbage collector」と明示している【1】。 |
| 高速性 | 低レベルの最適化が可能で、C/C++ と同等かそれ以上の実行速度を実現。 |
| 開発者満足度 | Stack Overflow 2023 年開発者調査で「最も愛されるプログラミング言語」第 1 位に選出【2】。 |
| 企業採用状況 | Microsoft(Azure IoT)、Amazon(Firecracker)、Google(Fuchsia)などがプロダクトの一部に Rust を導入。2023 年末時点で GitHub の「Octoverse」レポートは、Rust リポジトリ数が前年比 35 % 増加したと報告【3】。 |
| エディションの進化 | 2023 年にリリースされた Rust 1.73(edition 2023)では async‑await の安定化や std::sync::OnceLock の追加など、実務での採用ハードルがさらに下がった【4】。 |
ポイント
- 「安全」+「高速」は相反しないことを示す最新データは 2023 年版が最も信頼できる。
- 言語自体だけでなく、エコシステム(Cargo、crates.io)の成熟度が企業導入を後押ししている。
2. 開発環境の構築 ― rustup と Cargo の基本
2‑1. OS 別インストール手順
公式インストーラは rustup(ツールチェーン管理)と Cargo(ビルド・パッケージマネージャ)を一括で導入できる。以下のコマンドを端末に貼り付ければ完了する。
| OS | コマンド例 |
|---|---|
| Windows (PowerShell) | iwr https://static.rustup.rs -UseBasicParsing | iex |
| macOS / Linux | /bin/bash -c "$(curl -fsSL https://sh.rustup.rs)" |
インストール後、以下でバージョンを確認できる。
|
1 2 3 |
rustc --version # コンパイラ本体のバージョン cargo --version # ビルドツールのバージョン |
補足:必要なビルドツール(Linux)
| ディストリビューション | 追加でインストールすべきパッケージ |
|---|---|
| Debian / Ubuntu | sudo apt install build-essential |
| Fedora | sudo dnf groupinstall "Development Tools" |
| Arch Linux | sudo pacman -S base-devel |
参考:公式インストールガイド【5】
2‑2. Cargo の主要コマンド
| コマンド | 用途 |
|---|---|
cargo new <name> |
新規プロジェクト雛形を作成(--bin で実行ファイル、--lib でライブラリ) |
cargo build |
デバッグビルド(--release オプションで最適化ビルド) |
cargo run |
ビルド+実行を一括 |
cargo test |
ユニットテストの自動実行 |
cargo doc --open |
ドキュメント生成とブラウザ表示 |
cargo update |
Cargo.lock の依存バージョンを最新に更新 |
ベストプラクティス
- 依存はなるべく semver に従い、^(キャレット)でマイナーバージョンまで自動アップデートさせる。
- CI/CD ではcargo fmt --check && cargo clippy -- -D warningsを実行し、コードフォーマットと静的解析を必須化する。
3. メモリ安全機構の核心 ― 所有権・借用・ライフタイム
3‑1. 所有権とスコープ
- 所有者(owner):変数は唯一の所有者を持ち、所有権がスコープから抜けると自動的に
dropが呼ばれメモリが解放される。 - ムーブ(move) と コピー(Copy):サイズが 8 バイト以下かつ
Copyトレイト実装済みの型は暗黙的にコピー、その他は所有権が移動する。
|
1 2 3 4 5 6 7 |
fn main() { let s1 = String::from("Rust"); let s2 = s1; // ← 所有権が s2 にムーブされ、s1 は無効化 println!("{}", s2); // OK // println!("{}", s1); // コンパイルエラー: use of moved value `s1` } |
3‑2. 借用(イミュータブル / ミュータブル)
| 種類 | 同時取得可能数 |
|---|---|
イミュータブル参照 (&T) |
任意個数 |
ミュータブル参照 (&mut T) |
0 または 1 個(排他) |
|
1 2 3 4 5 6 7 8 9 10 11 |
fn main() { let mut data = vec![1, 2, 3]; // イミュータブル参照は複数取得可 let r1 = &data[0]; let r2 = &data[1]; println!("{} {}", r1, r2); // ミュータブル参照は排他 // let m = &mut data; // ← コンパイルエラー } |
出典:Zenn 記事「所有権・借用チェッカーの実践」【6】
3‑3. ライフタイム注釈
- ライフタイムは参照が有効な期間を型レベルで表現し、コンパイラに「どちらが長く生き残るか」を明示させる。
- 主に 関数シグネチャ や 構造体定義 で使用。
|
1 2 3 4 |
fn longest<'a>(x: &'a str, y: &'a str) -> &'a str { if x.len() > y.len() { x } else { y } } |
この例では、返り値の参照は引数 x と y のうち 短い方 と同じ寿命になることを保証している。
実務での活用例
- 複数スライスから最長文字列を抽出する API。
- GUI フレームワークで「ビューが生きている間だけデータ参照を保持」する設計。
4. unsafe の正しい使いどころ
| 用途 | 必要性の根拠 |
|---|---|
| FFI(外部 C ライブラリ呼び出し) | メモリレイアウトや呼び出し規約がコンパイラに把握できないため unsafe が必須。 |
| 生ポインタ操作 | ポインタの有効性・アラインメントは開発者が保証する必要がある。 |
| 低レベル最適化 / SIMD | 標準ライブラリでは提供されないハードウェア命令を直接呼び出すケース。 |
|
1 2 3 4 5 6 7 8 9 |
extern "C" { fn puts(s: *const i8); } fn hello_c() { let c_str = std::ffi::CString::new("Hello from C").unwrap(); unsafe { puts(c_str.as_ptr()); } } |
unsafe を安全に扱うチェックリスト
- 最小スコープ化:
unsafeブロックは可能な限り狭い範囲に限定。 - 前提条件の明示:コメントで「ポインタが非 NULL、アラインメント済み」などを書き残す。
- テストとレビュー:
cargo test --releaseで最適化ビルド時の未定義動作も検出できるようにする。
参考:Rustonomicon(公式 unsafe ガイド)【7】
5. ハンズオン ― 基本からベクタ操作まで体感
ステップ 1: Hello, world!
|
1 2 3 |
cargo new hello_memsafe --bin cd hello_memsafe |
src/main.rs
|
1 2 3 4 |
fn main() { println!("Hello, Rust!"); } |
実行:
|
1 2 3 |
cargo run # => Hello, Rust! |
ステップ 2: 所有権と借用の確認
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
fn take_ownership(s: String) { println!("{}", s); } // `s` がスコープ抜けで解放 fn borrow_ref(s: &String) { println!("{}", s); } fn main() { let a = String::from("Rust"); take_ownership(a); // println!("{}", a); // ← コンパイルエラー let b = String::from("安全"); borrow_ref(&b); println!("{}", b); // 借用後も使用可能 } |
ステップ 3: ライフタイムとベクタ参照
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
fn longest<'a>(x: &'a str, y: &'a str) -> &'a str { if x.len() > y.len() { x } else { y } } fn main() { let mut words = vec![ String::from("short"), String::from("much longer") ]; // ベクタ要素への参照はベクタ自体の寿命に束縛される let w1 = &words[0]; let w2 = &words[1]; println!("Longest: {}", longest(w1, w2)); } |
学習効果
- 所有権がムーブされた後は変数が無効になることを体感。
- Borrow Checker が競合を検出する様子をコンパイルエラーで確認。
- ライフタイム注釈が実際に安全な API を構築できる根拠になる。
6. 学習リソースと次のステップ
| 種類 | 推奨教材・リンク |
|---|---|
| 公式ドキュメント | https://doc.rust-lang.org/(「Learn」セクション)【8】 |
| The Rust Book(第 2 版) | 無料オンライン版:https://doc.rust-lang.org/book/ |
| Rust by Example | 実践的コード例が豊富:https://doc.rust-lang.org/rust-by-example/ |
| オンライン講座 | Udemy 「基礎から学ぶ Rust プログラミング入門」2024/04 更新版(動画+演習)【9】 |
| コミュニティ | Discord rust-lang、日本語ユーザー会 https://rust-jp.org/ |
学習ロードマップ(例)
- 環境構築 & Hello, world! – 1 日
- 所有権・借用・ライフタイム – 3–5 日でコード実装を繰り返す。
- Cargo エコシステム – クレート(
serde,reqwest,tokio)を組み合わせた小規模アプリを作成。 - 非同期プログラミング –
async/awaitとtokioのハンズオンでサーバー実装。 - FFI / unsafe – C ライブラリ呼び出しと安全境界の設計練習。
まとめ:本記事で環境構築・メモリ安全機構を体感したら、上記ロードマップに沿って実務レベルのプロジェクトへ挑戦すると学習効果が最大化します。
参考文献
- Rust Official Site, “no runtime or garbage collector” – https://www.rust-lang.org/ (2024‑03)
- Stack Overflow Developer Survey 2023 – https://insights.stackoverflow.com/survey/2023 (2024‑01)
- GitHub Octoverse 2023 Report – https://octoverse.github.com/ (2023‑12)
- Rust 1.73 Release Notes – https://blog.rust-lang.org/2023/11/16/Rust-1.73.html (2023‑11)
- rustup.rs – Installation Guide – https://rustup.rs/ (2024‑02)
- Zenn, 所有権・借用チェッカーの実践 (mk0812) – https://zenn.dev/mk0812/articles/ownership-borrow (2023‑08)
- Rustonomicon – Unsafe Code Guidelines – https://doc.rust-lang.org/nomicon/ (2024‑01)
- The Rust Programming Language – Official Book – https://doc.rust-lang.org/book/ (最新版)
- Udemy, 基礎から学ぶRustプログラミング入門 (pharmax) – https://www.udemy.com/course/rust-programming-basics/ (2024‑04)