Rust

初級 | 8分 で読める | 2026.04.24

公式ドキュメント

この記事の要点

所有権システムでメモリ安全性を保証、ガベージコレクタ不要
Result<T, E>Option<T>でエラーと欠損を型で表現
借用ライフタイムで参照の安全性をコンパイル時に検証

基本文法

構文説明
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
}

注意: StringVecなどヒープを使う型は、代入時に所有権がムーブします。元の変数は使えなくなるため、継続利用したい場合は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はコンパイルせず型チェックだけ行うので、開発中の確認が高速です。編集→チェック→修正のサイクルで活用できます。

参考リソース

関連記事

この技術を体系的に学びたいですか?

未来学では東証プライム上場企業のITエンジニアが24時間サポート。月額24,800円から、退会金0円のオンラインIT塾です。

メールで無料相談する
← 一覧に戻る