Rust

初級 | 8分 で読める | 2026.04.24

公式ドキュメント

概要

Rust は、所有権と借用によってメモリ安全性をコンパイル時に検査するシステムプログラミング言語です。このチートシートでは、基本文法、所有権、借用、ライフタイム、エラー処理、Cargo コマンドを初学者が確認しやすい順にまとめます。

最初に覚える最小セット

項目まず使う構文
不変変数let x = 5;
可変変数let mut x = 5;
関数fn add(a: i32, b: i32) -> i32
所有権let s2 = s1;
借用&value / &mut value
エラーResult<T, E> + ?
型チェックcargo check
テストcargo test

Rust は「値の所有者は誰か」「参照はどこまで有効か」を意識すると理解しやすくなります。コンパイルエラーは、安全に直すためのヒントとして読みます。

基本文法

構文説明
let x = 5;不変変数の宣言
let mut y = 10;可変変数の宣言
const MAX: u32 = 100;定数の宣言
fn add(a: i32, b: i32) -> i32関数定義
if x > 0 { ... } else { ... }条件分岐
loop { ... }無限ループ
while x < 10 { ... }条件付きループ
for i in 0..10 { ... }範囲のループ

ポイント: Rustの変数はデフォルトで不変です。可変にする場合は明示的にmutキーワードを付けます。これにより意図しない変更を防ぎます。

所有権ルール

ルール説明
各値は1つのオーナーを持つオーナーがスコープを抜けると値は破棄される
オーナーは1つだけ同時に複数の所有者は存在できない
let y = x; でムーブxの所有権がyに移り、xは無効化
let y = x.clone(); でコピーヒープデータを深くコピーして新しい所有者を作成
fn main() {
 let s1 = String::from("hello");
 let s2 = s1; // s1の所有権がs2にムーブ
 // println!("{}", s1); // エラー: s1は無効
 println!("{}", s2); // OK
}

注意: StringやVecなどヒープを使う型は、代入時に所有権がムーブします。元の変数は使えなくなるため、継続利用したい場合はclone()か借用を使います。

借用と参照

構文説明
&x不変参照(借用)
&mut x可変参照
*r参照の逆参照
ルール説明
不変参照は複数同時OK&x, &x, &x
可変参照は1つだけ&mut xが存在する間、他の参照は作れない
不変と可変は混在不可&xが存在する間、&mut xは作れない
fn main() {
 let mut s = String::from("hello");
 let r1 = &s; // OK
 let r2 = &s; // OK
 println!("{}, {}", r1, r2);
 
 let r3 = &mut s; // OK: r1, r2はもう使われない
 r3.push_str(" world");
}

実践メモ: 借用チェッカはコンパイル時に参照の競合を検出します。エラーが出たら、参照のスコープを短くするか、clone()で所有権を複製するかを検討します。

ライフタイム

構文説明
fn foo<'a>(x: &'a str)ライフタイムパラメータ'aを宣言
&'a Tライフタイム'aを持つ参照
struct S<'a> { r: &'a i32 }構造体フィールドに参照を持つ場合
'staticプログラム全体で有効なライフタイム
fn longest<'a>(x: &'a str, y: &'a str) -> &'a str {
 if x.len() > y.len() { x } else { y }
}

ポイント: ライフタイムは参照がどれだけ有効かをコンパイラに伝える注釈です。戻り値が参照の場合、引数のライフタイムと紐付けることでダングリングポインタを防ぎます。

エラー処理

説明
Result<T, E>成功値Ok(T)または失敗値Err(E)
Option<T>Some(T)または欠損None
unwrap()Ok/Someの値を取り出し、エラーならパニック
expect("msg")unwrap()にメッセージを付加
? 演算子エラーを呼び出し元に早期リターン
use std::fs::File;
use std::io::Read;

fn read_file(path: &str) -> Result<String, std::io::Error> {
 let mut file = File::open(path)?; // エラーなら即リターン
 let mut contents = String::new();
 file.read_to_string(&mut contents)?;
 Ok(contents)
}

実践メモ: ? 演算子はmatchunwrap()よりも簡潔でエラー伝播に適しています。関数の戻り値が Result のときだけ使えます。

構造体とトレイト

構文説明
struct Point { x: i32, y: i32 }構造体定義
impl Point { fn new() -> Self {...} }メソッド実装
trait Draw { fn draw(&self); }トレイト定義
impl Draw for Point { ... }トレイト実装
#[derive(Debug, Clone)]自動トレイト導出
#[derive(Debug)]
struct User {
 name: String,
 age: u8,
}

impl User {
 fn new(name: String, age: u8) -> Self {
 User { name, age }
 }
}

ポイント: #[derive]属性でDebug, Clone, PartialEqなどの一般的なトレイトを自動実装できます。手動実装よりも高速かつ安全です

パターンマッチ

構文説明
match x { ... }すべてのパターンを網羅する必要がある
Some(v) => ...Optionのマッチ
Ok(v) => ...Resultのマッチ
_ => ...すべての残りのケース
if let Some(v) = x { ... }単一パターンのマッチ
fn describe(x: Option<i32>) {
 match x {
 Some(v) if v > 0 => println!("正の数: {}", v),
 Some(0) => println!("ゼロ"),
 Some(_) => println!("負の数"),
 None => println!("値なし"),
 }
}

注意: matchは網羅性チェックがあるため、すべてのケースを処理しないとコンパイルエラーになります。漏れを防ぐために_で残りをキャッチします。

よく使うマクロ

マクロ説明
println!("x={}", x)フォーマット出力-
vec![1, 2, 3]ベクタ生成let v = vec![1, 2, 3];
panic!("error")パニック発生-
assert!(x == 5)アサーション-
assert_eq!(x, 5)等価性アサーションassert_eq!(v.len(), 3);

Cargo コマンド

コマンド説明
cargo new project_name新規プロジェクト作成
cargo buildビルド(デバッグ)
cargo build --releaseリリースビルド
cargo runビルド&実行
cargo testテスト実行
cargo check型チェックのみ(高速)
cargo doc --openドキュメント生成&表示

実践メモ: cargo checkはコンパイルせず型チェックだけ行うので、開発中の確認が高速です。編集→チェック→修正のサイクルで活用できます。

まとめ

Rust では、所有権、借用、ResultOption?cargo check を押さえると学習の詰まりを減らせます。unwrap() は学習中やテストでは便利ですが、アプリケーション本体ではエラーを呼び出し元へ返す設計を優先します。

標準ライブラリや言語仕様の詳細は、The Rust Programming Language と公式リファレンスを確認してください。

参考リソース

関連記事

← 一覧に戻る
PR
PR
PR
PR