English

高度な機能編 - match式

難易度: 🔴 上級
所要時間: 35分

📚 この章で学ぶこと


基本的なmatch式

リテラルパターン

int main() {
    int value = 2;

    match (value) {
        0 => println("zero"),
        1 => println("one"),
        2 => println("two"),
        3 => println("three"),
        _ => println("other"),
    }
    return 0;
}

構文:

ブロック本体

int main() {
    int value = 2;
    match (value) {
        0 => {
            println("This is zero");
            println("Nothing here");
        },
        1 => {
            println("This is one");
            println("First number");
        },
        _ => {
            println("Other number");
        },
    }
    return 0;
}

戻り値を返す(将来実装予定)

// 将来の構文
// string name = match (value) {
//     0 => "zero",
//     1 => "one",
//     2 => "two",
//     _ => "other",
// };

Enum値パターン

基本的な使い方

enum Status {
    Ok = 0,
    Error = 1,
    Pending = 2
}

void handle_status(int s) {
    match (s) {
        Status::Ok => println("Success!"),
        Status::Error => println("Failed!"),
        Status::Pending => println("Waiting..."),
    }
}

int main() {
    int status = Status::Ok;
    handle_status(status);
    return 0;
}

Enumとワイルドカード

enum Color {
    Red = 0,
    Green = 1,
    Blue = 2,
    Yellow = 3,
    Cyan = 4
}

void classify_color(int c) {
    match (c) {
        Color::Red => println("Primary: Red"),
        Color::Green => println("Primary: Green"),
        Color::Blue => println("Primary: Blue"),
        _ => println("Secondary color"),
    }
}

パターンガード

基本的なガード

int classify(int n) {
    match (n) {
        n if n < 0 => println("Negative"),
        n if n == 0 => println("Zero"),
        n if n > 0 => println("Positive"),
    }
    return 0;
}

構文: パターン if 条件式 => 本体

複雑な条件

int analyze(int x) {
    match (x) {
        x if x % 2 == 0 && x > 0 => println("Positive even"),
        x if x % 2 == 0 && x < 0 => println("Negative even"),
        x if x % 2 != 0 && x > 0 => println("Positive odd"),
        x if x % 2 != 0 && x < 0 => println("Negative odd"),
        _ => println("Zero"),
    }
    return 0;
}

範囲チェック

void check_score(int score) {
    match (score) {
        s if s >= 90 => println("Grade: A"),
        s if s >= 80 => println("Grade: B"),
        s if s >= 70 => println("Grade: C"),
        s if s >= 60 => println("Grade: D"),
        _ => println("Grade: F"),
    }
}

変数束縛パターン

変数の再利用

int describe(int n) {
    match (n) {
        x if x % 2 == 0 => println("{} is even", x),
        x if x % 2 == 1 => println("{} is odd", x),
    }
    return 0;
}

計算に使用

void fizzbuzz(int n) {
    match (n) {
        x if x % 15 == 0 => println("FizzBuzz"),
        x if x % 3 == 0 => println("Fizz"),
        x if x % 5 == 0 => println("Buzz"),
        x => println("{}", x),
    }
}

int main() {
    for (int i = 1; i <= 15; i++) {
        fizzbuzz(i);
    }
    return 0;
}

網羅性チェック

Enum型の網羅

enum TrafficLight {
    Red = 0,
    Yellow = 1,
    Green = 2
}

void handle_light(int light) {
    match (light) {
        TrafficLight::Red => println("Stop"),
        TrafficLight::Yellow => println("Caution"),
        TrafficLight::Green => println("Go"),
        // 全てのケースを網羅している
    }
}

網羅性エラー

// コンパイルエラー: すべてのケースが網羅されていない
/*
void incomplete(int light) {
    match (light) {
        TrafficLight::Red => println("Stop"),
        TrafficLight::Yellow => println("Caution"),
        // TrafficLight::Greenが欠けている!
    }
}
*/

ワイルドカードで解決

void with_default(int light) {
    match (light) {
        TrafficLight::Red => println("Stop"),
        TrafficLight::Yellow => println("Caution"),
        _ => println("Go or other"),
        // ワイルドカードで残りをカバー
    }
}

match vs switch

switchの場合

int main() {
    int value = 2;

    switch (value) {
        case(0) {
            println("zero");
        }
        case(1) {
            println("one");
        }
        case(2) {
            println("two");
        }
        else {
            println("other");
        }
    }
    return 0;
}

matchの場合

int main() {
    int value = 2;

    match (value) {
        0 => println("zero"),
        1 => println("one"),
        2 => println("two"),
        _ => println("other"),
    }
    return 0;
}

matchの利点:


実践例

HTTPステータスコード

enum HttpStatus {
    Ok = 200,
    NotFound = 404,
    InternalError = 500
}

void handle_response(int status) {
    match (status) {
        HttpStatus::Ok => println("Success"),
        HttpStatus::NotFound => println("Page not found"),
        HttpStatus::InternalError => println("Server error"),
        s if s >= 400 && s < 500 => println("Client error: {}", s),
        s if s >= 500 => println("Server error: {}", s),
        _ => println("Other status: {}", status),
    }
}

ゲームの状態管理

enum GameState {
    Menu = 0,
    Playing = 1,
    Paused = 2,
    GameOver = 3
}

void update_game(int state) {
    match (state) {
        GameState::Menu => println("Show menu"),
        GameState::Playing => println("Update game logic"),
        GameState::Paused => println("Show pause screen"),
        GameState::GameOver => println("Show game over"),
    }
}

数値の分類

void classify_number(int n) {
    match (n) {
        0 => println("Zero"),
        n if n > 0 && n < 10 => println("Small positive: {}", n),
        n if n >= 10 && n < 100 => println("Medium positive: {}", n),
        n if n >= 100 => println("Large positive: {}", n),
        n if n < 0 && n > -10 => println("Small negative: {}", n),
        n if n <= -10 => println("Large negative: {}", n),
    }
}

よくある間違い

❌ ワイルドカードの順序

// 間違い: ワイルドカードが先にあると他のパターンに到達しない
/*
match (value) {
    _ => println("Any"),  // これが全てマッチしてしまう
    0 => println("Zero"), // 到達不能
    1 => println("One"),  // 到達不能
}
*/

❌ 網羅性の不足

enum Status { Ok = 0, Error = 1 }

// エラー: すべてのケースが網羅されていない
/*
match (status) {
    Status::Ok => println("OK"),
    // Status::Errorが欠けている
}
*/

❌ カンマの忘れ

/*
match (value) {
    0 => println("zero"),
    1 => println("one")  // カンマがない!
    2 => println("two"),
}
*/

練習問題

問題1: 曜日判定

数値(1-7)を曜日名に変換してください。

解答例 ```cm void print_day(int day) { match (day) { 1 => println("Monday"), 2 => println("Tuesday"), 3 => println("Wednesday"), 4 => println("Thursday"), 5 => println("Friday"), 6 => println("Saturday"), 7 => println("Sunday"), _ => println("Invalid day"), } } int main() { for (int i = 1; i <= 7; i++) { print_day(i); } return 0; } ```

問題2: 成績判定

点数を成績(A-F)に変換してください。

解答例 ```cm void grade(int score) { match (score) { s if s >= 90 => println("A: Excellent"), s if s >= 80 => println("B: Good"), s if s >= 70 => println("C: Average"), s if s >= 60 => println("D: Pass"), s if s >= 0 => println("F: Fail"), _ => println("Invalid score"), } } int main() { grade(95); // A grade(85); // B grade(75); // C grade(65); // D grade(55); // F return 0; } ```

次のステップ

✅ match式の基本構文を理解した
✅ パターンガードが使える
✅ 網羅性チェックがわかった
⏭️ 次は with自動実装 を学びましょう

関連リンク


前の章: 型制約
次の章: with自動実装

最終更新: 2026-02-08