Rust プログラミング 入門

Rust完全ガイド 第1回 Rust入門と基礎

はじめに

Rustとは?

Rustは、安全性、速度、並行性を重視して設計されたプログラミング言語です。
Mozillaが開発を開始し、現在はRust Foundationによって管理されています。

一般的なプログラミング言語では、メモリ管理のミス並行処理のバグが発生しやすいですが、Rustは独自の所有権システム(Ownership)により、これらの問題をコンパイル時に防ぎます。

そのため、CやC++のような低レベルなシステムプログラミングだけでなく、Web開発や組み込みシステム、ゲーム開発など幅広い用途で利用されています。

Rustのコードはシンプルで堅牢な設計ができるため、最近ではGoogleやMicrosoft、AWSなどの大手企業も採用を進めています。

なぜRustを学ぶのか

Rustを学ぶべき理由はいくつかありますが、特に以下の点が重要です。

  • 学習価値が高い
    Rustは近年注目を集める言語であり、開発者向けアンケート(Stack Overflow Developer Survey)では**「最も愛されるプログラミング言語」として毎年上位にランクインしています。
    これは、Rustの設計思想が
    安全性・速度・並行性**を兼ね備えた理想的なものであることを示しています。
  • 幅広い活用シーン
    Rustはシステムプログラミングだけでなく、Web開発、ゲーム開発、ブロックチェーン、組み込みシステムなど多くの分野で活用されています。
    これにより、Rustを学ぶことで多様なプロジェクトに対応できるスキルが身につきます。

安全性の確保

Rustは、メモリ安全性を保証する機能を持っており、nullポインタ参照データ競合といったバグを防ぐことができます。
これは、CやC++のような手動メモリ管理が必要な言語と比べて大きな利点です。

パフォーマンスの高さ

Rustはコンパイルされた言語であり、CやC++に匹敵する高速な実行速度を持ちます。
ガベージコレクション(GC)を使用しないため、メモリ管理のオーバーヘッドが少なく、低レイテンシなアプリケーション開発に向いています。

並行処理の容易さ

Rustの所有権システムは、データ競合を防ぎつつスレッドセーフなコードを書けるように設計されています。
これにより、高速なマルチスレッドアプリケーションを安全に開発できます。

将来性の高さ

Rustは、GoogleのFuchsia OSMicrosoftのセキュリティ重視プロジェクトなど、次世代のシステム開発で採用が進んでいます。
近年、LinuxカーネルにもRustのコードが採用され始めており、今後の成長が期待されています。

Rustの特徴(安全性・速度・並行性)

Rustの最大の特徴は、以下の3つの要素に集約されます。

特徴説明
安全性(Safety)所有権システムによりメモリ安全性が保証される
速度(Performance)コンパイル言語であり、C/C++に匹敵する高速処理が可能
並行性(Concurrency)データ競合のない並行処理が可能で、スレッドセーフなプログラムを実現

安全性:メモリ管理の自動化とエラー防止

Rustは、コンパイル時にメモリの安全性をチェックし、ポインタの誤使用やデータ競合を防ぎます。
これは、所有権システムとライフタイム(Lifetime)によって実現されており、開発者が明示的にメモリ管理をする必要がありません。

速度:C/C++並みのパフォーマンス

Rustは、ガベージコレクションを持たずにメモリ管理を行うため、C/C++と同レベルの高性能なコードを記述できます。
また、ゼロコスト抽象化(Zero-cost abstraction)により、コードの可読性とパフォーマンスを両立させることが可能です。

並行性:スレッドセーフなプログラミング

Rustでは、データ競合(Data Race)をコンパイル時に防ぐことができるため、スレッドを使用した並行プログラムの開発が容易になります。
他の言語では難しい「スレッドセーフなコード」を簡単に書けるため、高性能なアプリケーション開発に向いています。

本記事の目的と学習方針

本記事では、Rustを初めて学ぶエンジニア向けに、基礎から応用まで体系的に解説していきます。
特に以下の3つの点を重視します。

  1. 実際に手を動かして学べる
    • 各章ごとにサンプルコードを用意し、Rustの動作を確認しながら学習できるようにします。
  2. Rustの設計思想を理解する
    • 単にコードの書き方を学ぶのではなく、Rustの安全性や所有権システムなど、なぜRustがこう設計されているのかを解説します。
  3. 実践的な開発に役立つ
    • 最終的には、実用的なRustアプリケーションを作成できるようにすることを目標とします。
    • Web開発、システムプログラミング、並行処理など、実際の開発で役立つスキルを習得します。

まとめ

Rustは、安全性・速度・並行性を兼ね備えた次世代のプログラミング言語であり、多くの企業が採用を進めています。
特に、メモリ管理の自動化スレッドセーフな並行処理が求められるプロジェクトでは、CやC++に代わる有力な選択肢となっています。

本シリーズでは、Rustの基礎から実践的な応用までを徹底解説していきます。
まずは、環境構築と基本的なRustのコードを書きながら学習を進めていきましょう!

Rustのインストールと環境構築

Rustを学ぶためには、まず開発環境を整える必要があります。
Rustはクロスプラットフォーム対応の言語であり、Windows, macOS, Linuxのすべてで簡単にインストールできます。

環境構築の方法を順番に解説し、最初のRustプログラムを動かすところまで進めていきましょう。

Rustのインストール(Windows, macOS, Linux)

Rustの公式推奨インストール方法は、rustupを使用する方法です。
rustupはRustのバージョン管理ツールであり、Rustのインストールやアップデートを簡単に行えます。

Windowsでのインストール

  1. 公式サイトからインストーラーをダウンロード
    • Rust公式サイト にアクセスし、「Install Rust」をクリックします。
    • Windowsの場合、rustup-init.exeがダウンロードされます。
  2. インストーラーを実行
    • rustup-init.exeを開き、インストールを進めます。
    • 基本的にはデフォルト設定でOKですが、カスタム設定も可能です。
  3. インストールが完了したら、ターミナルで確認
    • コマンドプロンプトまたはPowerShellを開き、以下のコマンドを実行します。
    rustc --version
    • Rustのバージョンが表示されれば、インストール成功です。

macOSでのインストール

macOSでは、ターミナルを使用してRustをインストールできます。

  1. ターミナルを開く
  2. 以下のコマンドを実行 curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
  3. 指示に従ってインストールを完了する
  4. インストールが完了したら、以下のコマンドで確認rustc --version
    • Rustのバージョン情報が表示されれば成功です。

Linuxでのインストール

Linuxでも、macOSと同じコマンドを使用します。

  1. ターミナルを開く
  2. 以下のコマンドを実行 curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
  3. インストール後、以下のコマンドで確認 rustc --version

Linuxでは、パッケージマネージャ(aptdnf)を使ってRustをインストールする方法もありますが、rustupの方が管理しやすいため推奨されます。

rustupを使ったバージョン管理

Rustの開発では、バージョン管理が重要になります。
rustupを使うと、異なるバージョンのRustを簡単に切り替えることができます。

Rustのバージョン確認

rustc --version

Rustのアップデート

rustup update
  • 最新のRustにアップデートできます。

特定のバージョンのインストール

rustup install 1.65.0
  • Rust 1.65.0をインストールする場合の例です。

プロジェクトごとに異なるバージョンを設定

rustup override set 1.65.0
  • このコマンドを実行したディレクトリ内では、指定したバージョンのRustが使用されます。

Rustの基本ツール(cargo, rustc, rustfmtなど)

Rustの開発では、以下のツールを使用します。

ツール説明
rustcRustのコンパイラ。ソースコードをバイナリに変換
cargoRustのビルドツール&パッケージ管理ツール
rustfmtRustのコード整形ツール
clippyRustの静的解析ツール(コード品質向上)

cargoの基本操作

cargoはRust開発に必須のツールです。
プロジェクトの作成やビルド、テスト、クレート管理が可能です。

プロジェクトの新規作成
cargo new my_project

my_project という新しいプロジェクトを作成します。

コードをビルドする
cargo build

プロジェクトをコンパイルして実行ファイルを生成します。

コードを実行する
cargo run

main.rs をコンパイルして実行します。

依存関係を管理する
cargo add serde

serde(Rustのシリアライゼーションライブラリ)を追加します。

コードのフォーマットを整える
rustfmt main.rs

main.rs のコードを整形します。

初めてのRustプログラム(Hello, World!)

Rustの環境が整ったら、最初のプログラムを実行してみましょう。
Rustでは、main.rsに以下のコードを書くことで「Hello, World!」を出力できます。

コード例

fn main() {
    println!("Hello, world!");
}

実行手順

1.新しいプロジェクトを作成する
cargo new hello_rust
2.ディレクトリを移動する
cd hello_rust
3.プログラムを実行する
cargo run

ターミナルに以下のように表示されれば成功です。

Hello, World!

まとめ

Rustの環境構築は、rustupを使用すれば簡単に行えます。
cargoを活用することで、プロジェクトの作成や管理がスムーズになります。

最初のプログラム「Hello, World!」を実行することで、Rustの基本的な開発フローを体験できました。
次のステップでは、Rustの基本構文やデータ型について学んでいきましょう。

プログラムの基本構造

Rustの環境構築が完了したら、次にRustの基本的なプログラムの構造を学びましょう。
Rustのプログラムは、シンプルな構造を持ちつつも、安全で効率的な設計が可能です。

まずは、Rustのプログラムの最小構成であるfn main()関数から学び、println!マクロを使って出力を行い、最終的にcargo runで実行するまでの流れを確認します。

fn main()関数

Rustのプログラムは、fn main()関数から実行が始まります。
これは、C言語やPythonのmain関数と同じ役割を持っています。

基本構造

以下がRustにおける最もシンプルなプログラムです。

fn main() {
    println!("Hello, world!");
}
  • fn は関数を定義するキーワードです。
  • main はRustのエントリーポイントとなる関数であり、必ず定義する必要があります。
  • 波括弧 {} の中にプログラムの処理を記述します。
  • セミコロン ; はRustにおいて文の終わりを示す記号です。

Rustでは、main関数がないとプログラムが実行できないため、必ず定義しておきましょう。

println!マクロ

Rustで標準出力(コンソールに文字を表示)するには、println!マクロを使用します。
println!マクロを使うことで、簡単に文字列を出力できます。

基本的な使い方

fn main() {
    println!("Hello, world!");
}

このコードを実行すると、ターミナルに以下のように表示されます。

Hello, Rust!

文字列のフォーマット出力

println!マクロは、変数や数値を埋め込んで出力することもできます。

fn main() {
    let name = "Alice";
    let age = 25;
    
    println!("名前: {}, 年齢: {}", name, age);
}

出力結果:

名前: Alice, 年齢: 25
  • {} はプレースホルダーで、println!内の変数が順番に代入されます。
  • 変数の型を意識せずに使えるため、フォーマット出力が簡単にできます。

また、数値のフォーマットも可能です。

fn main() {
    let pi = 3.14159;
    println!("円周率は {:.2} です", pi);
}

出力結果:

円周率は 3.14 です
  • {:.2} のように書くことで、小数点以下2桁まで表示できます。

このように、Rustのprintln!マクロはとても柔軟で便利な出力方法を提供しています。

cargo runによる実行

Rustでは、cargoを使うことで簡単にプログラムを実行できます。
cargo run を使用すると、コンパイルと実行を一度に行うことができます。

基本的な実行方法

1.新しいRustプロジェクトを作成する
cargo new my_project
2.プロジェクトのディレクトリへ移動
cd my_project
3.プログラムを実行する
cargo run

このコマンドを実行すると、以下のような出力が表示されます。

   Compiling my_project v0.1.0 (/path/to/my_project)
    Finished dev [unoptimized + debuginfo] target(s) in 0.47s
     Running `target/debug/my_project`
Hello, Rust!

cargo runの内部動作

cargo run は内部で以下の処理を行っています。

  1. cargo build でコードをコンパイル
  2. 生成された実行ファイルを実行 (target/debug/my_project)

これにより、毎回手動でコンパイルする手間が省け、開発の効率が向上します。

リリースビルド(最適化版)の実行

通常のcargo runデバッグモードで実行されます。
高速な実行が必要な場合は、リリースビルドを使用しましょう。

cargo build --release

このコマンドを実行すると、最適化された実行ファイルが target/release/ ディレクトリに生成されます。

実行方法

./target/release/my_project

リリースビルドは最適化されているため、実行速度が向上しますが、コンパイルに時間がかかる点に注意が必要です。

まとめ

Rustのプログラムは、fn main()関数をエントリーポイントとして実行されます。
標準出力には println!マクロ を使い、フォーマットを活用すると便利です。

また、cargo runを使えば、簡単にコンパイル&実行が可能であり、リリースビルドを活用すれば最適化されたプログラムを実行できます。

次のステップでは、Rustの変数やデータ型について詳しく学んでいきましょう。

変数とデータ型

Rustでは、すべての値には型があり、変数を宣言してデータを管理することが基本になります。
Rustの型システムは、安全性とパフォーマンスを両立する設計がされており、厳密な型チェックが行われます。

この章では、変数の宣言方法や基本的なデータ型について学びましょう。

letによる変数宣言

Rustでは、変数を宣言する際にletキーワードを使用します。
基本的な変数の宣言方法は以下の通りです。

fn main() {
    let x = 5;
    println!("x の値は: {}", x);
}

このコードでは、変数x整数の5を代入し、println!で出力しています。

Rustの変数はデフォルトでイミュータブル(不変)です。
つまり、一度値を代入すると変更できません。

以下のコードはエラーになります。

fn main() {
    let x = 5;
    x = 10; // エラー: `x`は変更できない
}

Rustのこの仕様により、不意な値の変更を防ぎ、安全なプログラムの実装が可能になります。

可変変数 (mut)

変数を変更可能にするには、mutキーワードを使います。

fn main() {
    let mut x = 5;
    println!("最初の値: {}", x);

    x = 10; // 値の変更
    println!("変更後の値: {}", x);
}

このコードは、変数xの値を5から10に変更し、正常に動作します。
mutをつけることで、Rustの安全性を保ちながら、必要な箇所で値を変更できるようになります。

ただし、不要なmutは使用しないようにしましょう。
イミュータブルな変数の方が、スレッドセーフなコードを作りやすく、バグを減らすことができます。

スカラー型(整数型・浮動小数点型・ブール型・文字型)

Rustのスカラー型は、単一の値を持つ基本データ型です。

説明
整数型符号あり/なしの整数i32 = 42, u8 = 255
浮動小数点型小数を扱うf32 = 3.14, f64 = 2.718
ブール型真偽値(true / falsebool = true
文字型Unicode文字(1文字のみ)char = 'A'

整数型

Rustでは、整数型は符号あり (i) と符号なし (u) の両方が用意されています。

fn main() {
    let a: i32 = -10; // 符号あり整数
    let b: u8 = 255;  // 符号なし整数
    println!("a: {}, b: {}", a, b);
}

整数型の種類は以下の通りです。

ビット数範囲 (符号あり i / 符号なし u)
i8 / u88-128 ~ 127 / 0 ~ 255
i16 / u1616-32,768 ~ 32,767 / 0 ~ 65,535
i32 / u3232約±21億 / 0 ~ 約42億
i64 / u6464巨大な数値範囲
i128 / u128128非常に大きな数値範囲

特に指定しない場合、Rustの整数型はi32がデフォルトになります。

浮動小数点型

Rustにはf32f64の2種類の浮動小数点型があります。

fn main() {
    let pi: f64 = 3.14159; // デフォルトは f64
    let e: f32 = 2.718;
    println!("pi: {}, e: {}", pi, e);
}

浮動小数点型のデフォルトはf64で、これはより高精度で高速な処理ができるためです。

ブール型 (bool)

Rustでは、真偽値はboolで表現されます。

fn main() {
    let is_rust_fun: bool = true;
    println!("Rustは楽しい? {}", is_rust_fun);
}

文字型 (char)

Rustのchar型は、Unicode文字を1文字だけ格納できます。

fn main() {
    let letter: char = 'R';
    let emoji: char = '😊';
    println!("文字: {}, 絵文字: {}", letter, emoji);
}

Rustでは、文字列を扱う専用の型は char とは別に String 型 と &str 型 が存在します。
文字列については 第3回「Rustのデータ構造」で詳しく解説 するので、ここでは char 型だけを押さえておきましょう。

複合型(タプル・配列)

Rustでは、複数の値をまとめて扱う複合型が用意されています。
代表的なものに**タプル(Tuple)配列(Array)**があります。

タプル (tuple)

タプルは異なる型の値を1つの変数に格納できるデータ型です。

fn main() {
    let user: (i32, f64, &str) = (30, 72.5, "Alice");
    println!("年齢: {}, 体重: {}, 名前: {}", user.0, user.1, user.2);
}
  • タプルの要素は user.0 のようにインデックスでアクセスできます。

配列 (array)

配列は同じ型の値をまとめて格納するデータ型です。

fn main() {
    let numbers: [i32; 3] = [10, 20, 30];
    println!("最初の値: {}", numbers[0]);
}
  • 配列の長さは固定で、動的に変更できません。
  • インデックス([0])で要素にアクセスできます。

まとめ

これで第1回「Rust入門と基礎」が終了しました。
ここまでで、Rustの環境構築から、プログラムの基本構造、変数とデータ型の基礎までを学びました。

Rustは、安全性とパフォーマンスを両立したプログラミング言語です。
その基盤となる所有権システムや型システムの厳密さは、最初は少し慣れが必要ですが、理解すれば強力なツールとなります。

次回の第2回「制御フローと関数」では、Rustの条件分岐やループ、関数の作成方法について詳しく解説していきます。
Rustの実用的なプログラムを書くために、制御フローの知識は欠かせません。
ぜひ、次のステップへ進んでみましょう!

  • この記事を書いた人

ふくまる

機械設計業をしていたが25歳でエンジニアになると決意して行動開始→ 26歳でエンジニアに転職→ 28歳でフリーランスエンジニアに→ 現在、34歳でフリーランス7年目 Go案件を受注中 Go,GCPが得意分野

-Rust, プログラミング, 入門