第1章 Rust の特徴と開発環境の構築
Rust(ラスト)は、信頼性と処理速度を極めて高い次元で両立させた現代的なシステムプログラミング言語です。
長年、C 言語や C++ が担ってきた OS、ブラウザエンジン、ゲームエンジン、ネットワーク基盤などの高速な領域から、CLI ツールや Web サーバー、デスクトップアプリまで、幅広い分野で採用が進んでいます。本章では、Rust が注目される理由と、手元の環境ですぐに開発を始めるためのセットアップ手順を学びます。
1.1 なぜ Rust なのか?3つの大きな特徴
Rust が多くの開発者から支持される背景には、主に 3 つの設計思想があります。
1. ガベージコレクション(GC)なしのメモリ安全性
Java や Go、Python などの言語では、プログラムの実行中に不要になったメモリを自動で掃除する「ガベージコレクション(GC)」が動作します。GC は便利ですが、掃除のためにプログラムの実行が一瞬止まる(GC ポーズ)ことがあります。
一方、従来の C/C++ では開発者が手動でメモリの確保と解放を管理していたため、解放忘れによるメモリリークや、すでに解放されたメモリへの不正アクセス(ダングリングポインタ)といった重大なバグやセキュリティ脆弱性が頻発していました。
Rust は「所有権(Ownership)」という独自の仕組みにより、プログラムの実行時ではなく「コンパイル時(ビルド時)」にメモリの安全性を検証します。そのため、GC なしで C/C++ と同等に高速に動きながら、メモリに起因するクラッシュやセキュリティ欠陥をゼロにします。
2. ゼロコスト抽象化
Rust は、高水準な抽象化(オブジェクト指向的な構造体、パターンマッチ、イテレータなど)を提供しながらも、それらが実行時の速度低下を引き起こさないように設計されています。
これを「ゼロコスト抽象化(Zero-cost abstractions)」と呼びます。開発者が読みやすくきれいに書いた抽象的なコードは、コンパイラによって最も効率的な機械語へと最適化されます。
3. データ競合のない並行処理
現代の CPU は複数のコアを持っています。複数の処理を同時に動かす並行プログラミングでは、同じデータに対して複数の処理が同時に書き込みを行うことで起きる「データ競合(Data Race)」が最も解決しにくいバグの一つでした。
Rust では、型システムと所有権のルールによって、データ競合が発生する可能性のあるコードをコンパイルの段階で確実に検出してエラーにします。これにより、安全かつ高速なマルチスレッド処理を安心して記述できます。
1.2 開発環境のセットアップ
Rust のツールチェーンは、公式のインストーラーである rustup を使用して導入・管理します。
インストール手順
OS に応じて以下のコマンドを実行します。
Linux や macOS では、ターミナルで以下のシェルスクリプトを実行します。
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
Windows では、公式サイト(https://www.rust-lang.org/tools/install)からインストーラー(rustup-init.exe)をダウンロードして実行します。また、Windows でのビルドには「C++ Build Tools」(Visual Studio Installer から入手可能)が必要です。
インストールが完了したら、新しいターミナルを開き、正しく導入されたか確認します。
rustc --version
cargo --version
rustc(Rust コンパイラ)と cargo(ビルドツール兼パッケージマネージャー)のバージョン番号が表示されれば、環境構築は完了です。
1.3 初めてのプロジェクト作成と Cargo
Rust では、コードのコンパイル、外部ライブラリ(クレート)の管理、テストの実行などをすべて cargo コマンドで一元管理します。
プロジェクトの新規作成
以下のコマンドで、新しいバイナリ(実行可能プログラム)プロジェクトを作成します。
cargo new hello_world
生成されたディレクトリ構造は以下のとおりです。
hello_world/
├── Cargo.toml
└── src/
└── main.rs
プロジェクトの設定ファイル(Cargo.toml)
Cargo.toml はプロジェクトのメタ情報と依存関係を記述する設定ファイルです。
[package]
name = "hello_world"
version = "0.1.0"
edition = "2021"
[dependencies]
ソースコード(src/main.rs)
自動生成された src/main.rs を確認します。
fn main() {
println!("Hello, world!");
}
Rust プログラムの実行は常に main 関数から始まります。末尾に ! が付いている println! は関数ではなく、コンパイル時にコードを展開する「マクロ(Macro)」です。
頻出する Cargo コマンド
開発中に日常的に使用する基本コマンドは以下の 4 つです。
# プロジェクトをビルドして即座に実行する
cargo run
# コードに文法エラーや型エラーがないかを高速に検証する(バイナリを生成しないため超高速)
cargo check
# 開発用(デバッグ情報付き)のバイナリをビルドする(target/debug/ に出力)
cargo build
# 最適化を施した本番用(リリース用)の高速バイナリをビルドする(target/release/ に出力)
cargo build --release
日常の開発では、コードを書くたびに cargo check を走らせてコンパイラによるチェックを受け、動作確認の際に cargo run を実行するのが標準的な開発サイクルです。