Rust: Rust入門と開発環境のセットアップ:この安全で高性能なシステムプログラミング言語について知る
Rustは、誰もが信頼性が高く効率的なソフトウェアを構築できるようにする言語です。ガベージコレクションは備えていませんが、メモリの安全性を保証しています。
このチュートリアルは、少なくとも1つのプログラミング言語について基本的な知識を持つ開発者を対象としています。C/C++、Java、Python、JavaScriptのいずれのバックグラウンドをお持ちの方であっても、Rustの所有権システムとゼロコストの抽象化は、「安全性」に対する理解を一新することでしょう。Rustは、Stack Overflowの開発者アンケートにおいて、数年にわたり「最も愛されているプログラミング言語」に選ばれています。
1. 学習内容
- Rustとは?その中核となる設計思想
- RustとC/C++/Goの違い、およびそれぞれの適切な活用シーン
- rustup を使用して、Windows、macOS、または Linux に Rust をインストールする
- Cargo を使ってプロジェクトを作成、構築、実行する
- 初めてのRustプログラムを作成して実行する
- Rustのエコシステム(crates.ioおよび標準ライブラリ)
2. システムプログラマーの物語
(1) 『アゴニー:C言語の悪夢』
トムは組み込みシステムエンジニアです。ある日、彼にある緊急の任務が割り当てられました:
「このWebサービスのメモリ使用量を300MBから50MB未満に削減しつつ、絶対にクラッシュしないようにする。」
彼はこれをC言語で開発し、次のことを発見した。
- メモリを手動で管理すると、コード内に
mallocやfreeが 30 箇所以上出現してしまいます。1 箇所を修正しても、別の箇所を見落とす可能性があります。 - Nullポインタが原因で、オンラインサービスが週に2回クラッシュし、その修正のために真夜中に起こされた
- バッファオーバーフロー—セキュリティチームから「リモート攻撃のリスクがある」との連絡があった。
- テストの作成?C言語の場合、テストフレームワークを自分で構築する必要があり、CIを立ち上げて稼働させるのに2日かかります。
結局、彼は何を選んだの? Rustに乗り換えた。
(2) Rustによる解決策
同じタスクについて、トムはRustで次のように記述しました:
fn main() {
let msg = String::from("Hello, secure world!");
// Compiler Guarantees: msg memory is automatically released when it goes out of scope.
// Not necessary malloc, nor free
println!("{}", msg);
}
所要時間:コンパイルが成功すれば=安全。Rustコンパイラは、コンパイル中にメモリエラーを検出します。ValgrindもSanitizerも不要です。コンパイルできれば、安全です。
それがRustの素晴らしいところだ。コンパイル時にメモリエラーを排除し、実行時のオーバーヘッドをゼロに抑える。その設計思想は、「安全性は開発者の注意によって達成されるのではなく、コンパイラによって保証される」というものだ。
3. Rustとは何か?
Rustは、2015年にMozillaの研究者であるGraydon Hoareによって開発されたシステムレベルのプログラミング言語であり、もともとはFirefoxのブラウザエンジン向けに設計されたものです。
(1) Rustの3つの基本原則
graph LR
A[Rust Three Major Commitments] --> B[Zero-Cost Abstraction]
A --> C[Memory Safety]
A --> D[Concurrency-Safe]
B --> E[Expressiveness of High-Level Languages<br>Assembly-Level Performance]
C --> F[Ownership + Borrow<br>Eliminating Memory Errors at Compile Time]
D --> G[Send+Sync trait<br>Data race detected at compile time]
| カテゴリ | 説明 |
|---|---|
| ゼロコストの抽象化 | 高水準言語の表現力とアセンブリ言語のパフォーマンス。実行時のオーバーヘッドなし |
| メモリ安全性の保証 | 所有権 + 借用 + ライフサイクル;コンパイラは、コンパイル時に、ヌルポインタ、ワイルドポインタ、データ競合が存在しないことを保証する |
| 安全な並行処理 | Send および Sync トレイトを使用することで、並行処理に関するエラーをコンパイル時に検出できるようになります |
(2) Rust 対 C/C++ 対 Go
| ディメンション | C/C++ | Go | Rust |
|---|---|---|---|
| メモリ管理 | 手動によるmalloc/free | GC(ガベージコレクション) | 所有権および借用チェック(コンパイル時) |
| パフォーマンス | 非常に高い | 高い(GCの停止あり) | 非常に高い(実行時間ゼロ) |
| セキュリティへの取り組み | なし(プログラマー次第) | 一部(GCによりメモリリークを防止) | 完全(コンパイル時に保証) |
| 並行処理モデル | pthreads(マニュアル) | goroutine + チャネル | std::thread + Send/Sync トレイト |
| パッケージ管理 | Makefile / CMake | go mod | Cargo(標準機能) |
| 習得の難易度 | 中~高(ヒントが邪魔に感じられる場合がある) | 低 | 中~高(チェッカーを借りる) |
4. Rust をインストールする
(1) rustup を使用してインストールする
Rust をインストールする推奨方法は、Rust のバージョン管理ツールである rustup を使用することです。
# Run in the terminal (Windows requires Visual Studio C++ Build Tools to be installed first)
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
インストール後、バージョンを確認してください:
rustc --version # Output: rustc 1.86.0 (05f9846f8 2025-03-31)
cargo --version # Output: cargo 1.86.0 (version number)
(2) Windowsに関する特記事項
Windows ユーザーは、まず Visual Studio Build Tools(または Visual Studio 2019 以降)をインストールし、「C++ によるデスクトップ開発」ワークロードを選択する必要があります。Rust は MSVC リンカーに依存しています。
(3) 更新とアンインストール
rustup update # Update to the latest version
rustup self uninstall # Uninstall (for cache retention, use uninstall rather than directly deleting the directory)
5. 初めてのRustプログラム
▶ サンプル:Hello World (難易度 ⭐)
// ============================================
// First Rust Program: Print Hello World
// ============================================
fn main() {
println!("Hello, world!");
}
出力:
Hello, world!
fn main()は、すべての Rust プログラムのエントリポイントです。println!は、ターミナルにテキストを出力するために使用されるマクロです(!に注意)。
▶ サンプル:Cargo を使ったプロジェクトの作成 (難易度 ⭐)
# Create a New Project
cargo new hello_cargo
cd hello_cargo
cargo new は、以下の構造を生成します:
hello_cargo/
├── Cargo.toml # Project Configuration File (Dependencies, Metadata)
├── src/
│ └── main.rs # Source Code Entry Point
Cargo.toml 内容:
[package]
name = "hello_cargo"
version = "0.1.0"
edition = "2021"
コンパイルして実行:
cargo build # Compilation (generates target/debug/ directory)
cargo run # Compilation + Run
出力:
Hello, world!
CargoはRustのパッケージマネージャー兼ビルドシステムです。
cargo buildデバッグビルドを生成します;cargo run1つのコマンドでコンパイルと実行を行います;cargo checkバイナリを生成せずに構文チェックのみを行います(処理が高速です)。
▶ サンプル:簡単な電卓(難易度 ⭐⭐)
// ============================================
// A Simple Addition Calculator
// ============================================
fn main() {
let a: i32 = 10; // i32 is a 32-bit signed integer
let b: i32 = 20; // Rust type annotations use a colon
let sum = a + b;
println!("{} + {} = {}", a, b, sum);
}
出力:
10 + 20 = 30
Rustの変数は、デフォルトでは不変です。ここでは、
letを使用して宣言されています。後でその値を変更する必要がある場合は、let mutを使用する必要があります。型注釈: i32は省略可能です。コンパイラは文脈から型を推論することができます。
▶ サンプル:総合演習—温度の換算と報告(難易度 ⭐⭐)
// ============================================
// Comprehensive Example: Temperature Conversion + Simple Report Generation
// Demo Variables, Types, Basic Syntax, Such as Formatted Output
// ============================================
fn celsius_to_fahrenheit(celsius: f64) -> f64 {
celsius * 9.0 / 5.0 + 32.0
}
fn fahrenheit_to_celsius(fahrenheit: f64) -> f64 {
(fahrenheit - 32.0) * 5.0 / 9.0
}
fn main() {
let cities = ["Beijing", "Shanghai", "Guangzhou"];
let temps_c = [28.5, 31.2, 33.8];
println!("=== City Temperature Report ===");
println!("{:<12} {:>10} {:>10}", "City", "Celsius(°C)", "Fahrenheit(°F)");
println!("{}", "-".repeat(34));
let mut index = 0;
while index < cities.len() {
let c = temps_c[index];
let f = celsius_to_fahrenheit(c);
println!("{:<12} {:>10.1} {:>10.1}", cities[index], c, f);
index += 1;
}
let freezing_f: f64 = 32.0;
let freezing_c = fahrenheit_to_celsius(freezing_f);
println!("\nFreezing Point: {:.1}°F = {:.1}°C", freezing_f, freezing_c);
const BOILING_C: f64 = 100.0;
let boiling_f = celsius_to_fahrenheit(BOILING_C);
println!("Boiling Point: {:.1}°C = {:.1}°F", BOILING_C, boiling_f);
}
出力:
=== City Temperature Report ===
City Celsius(°C) Fahrenheit(°F)
----------------------------------
Beijing 28.5 83.3
Shanghai 31.2 88.2
Guangzhou 33.8 92.8
Freezing Point: 32.0°F = 0.0°C
Boiling Point: 100.0°C = 212.0°F
この包括的な例では、関数の定義、定数の宣言、配列の反復処理、書式付き出力、温度換算式などを網羅しており、Rustの基本構文を徹底的に解説しています。
▶ サンプル:数字当てゲーム(難易度 ⭐⭐)
use std::io;
fn main() {
let secret = 42; // Hidden answer (random numbers will be used in subsequent lessons)
println!("🎯 Guess the Number Game! Range 1-100");
loop {
println!("Please enter your guess:");
let mut guess = String::new();
io::stdin()
.read_line(&mut guess)
.expect("Failed to read input");
let guess: i32 = match guess.trim().parse() {
Ok(num) => num,
Err(_) => {
println!("⚠️ Please enter a valid number!");
continue;
}
};
match guess.cmp(&secret) {
std::cmp::Ordering::Less => println!("Too small! ⬆️"),
std::cmp::Ordering::Greater => println!("Too big! ⬇️"),
std::cmp::Ordering::Equal => {
println!("🎉 Congratulations, you got it right! The answer is {}", secret);
break;
}
}
}
}
この例は、
loop、match、標準ライブラリioの基本的な使い方とエラー処理を解説するもので、Rustの公式チュートリアルにおける定番の入門プロジェクトです。
6. Rustエコシステムの概要
Rustのエコシステムは、3つの主要なツールを中心に構成されています:
| ツール | 用途 | コマンド |
|---|---|---|
| rustc | Rustコンパイラ | rustc main.rs |
| rustup | Rustのバージョン管理 | rustup toolchain install nightly |
| Cargo | パッケージ管理 + ビルド | cargo build / run / test / doc |
オープンソースのパッケージは crates.io (https://crates.io) で公開されており、現在15万以上のパッケージが登録されています。代表的なパッケージとしては、serde(シリアライゼーション)、clap(コマンドライン引数)、tokio(非同期ランタイム)などがあります。
❓ よくある質問
cargo check と cargo build の違いは何ですか?cargo check は構文チェックと型チェックのみを行い、バイナリファイルを生成しないため、処理がはるかに高速です。📖 まとめ
- Rustはシステムレベルのプログラミング言語であり、その主な特長は、コンパイル時のメモリ安全性とゼロコストの抽象化である。
- C/C++ と比べると、Rust はメモリを自動的に管理します。Go と比べると、GC による停止がありません。
rustupを使用して Rust をインストールします。複数のバージョンの管理に対応しています。Cargoは Rust のパッケージ管理およびビルドシステムであり、cargo new/cargo build/cargo runはその 3 つの主要な機能です- Rustの所有権システムは、その最も特徴的な機能です(これについては第8課で詳しく解説します)
- このエコシステムの中核をなすのは crates.io であり、そこではコミュニティが活発に活動しており、成長を続けています
📝 練習問題
- 難易度 ⭐:
cargo newを使用してmy_first_rustという名前のプロジェクトを作成し、main.rsを修正して自分の名前を出力するようにし、cargo runを使用して実行してください。 - 難易度 ⭐⭐:例3を基に、引き算、掛け算、割り算の演算を追加し、さまざまな種類の演算の結果を観察します(整数の割り算は切り捨てられるか?)。
- 難易度 ⭐⭐⭐:
rustup docが開いたRustの公式ドキュメントを読み、「Ownership」のセクションを見つけて、自分の言葉で3文に要約してください。その要約を、知り合いのRust開発者に送って、内容が正しいかどうか確認してもらってください。