翻訳の対象範囲は一部です。完全な技術リファレンスは英語の原文を参照してください。 英語版を見る →

Pattern Matching

Exhaustive pattern matching with match expressions, guards, and nested patterns.

パターンマッチング

match 式は、値に対する網羅的なパターンマッチングを提供します。コンパイラはすべてのケースが網羅されているかを検査し、到達不能なアームについて警告を出します。

基本的なマッチング

fn describe(x: i32) -> i64 {
    match x {
        0 => 0,
        1 => 1,
        _ => 2,
    }
}

ワイルドカード _ は任意の値にマッチし、キャッチオールとして使用されます。

enumに対するマッチング

enum Shape {
    Circle(f64),
    Rectangle(f64, f64),
    Triangle(f64, f64, f64),
}

fn sqrt(x: f64) -> f64 { x }

fn area(s: Shape) -> f64 {
    match s {
        Shape::Circle(r) => 3.14159 * r * r,
        Shape::Rectangle(w, h) => w * h,
        Shape::Triangle(a, b, c) => {
            let s = (a + b + c) / 2.0
            sqrt(s * (s - a) * (s - b) * (s - c))
        },
    }
}

バリアントを省略すると、コンパイラは非網羅的なマッチングについてエラーを報告します。

ガード

パターンアームに if ガードを含めて、追加の条件を指定できます:

fn classify_temp(celsius: f64) -> i64 {
    match celsius {
        t if t < 0.0 => 0,
        t if t < 20.0 => 1,
        t if t < 35.0 => 2,
        _ => 3,
    }
}

構造体に対するマッチング

struct Point { x: f64, y: f64 }

fn quadrant(p: Point) -> i64 {
    match p {
        Point { x, y } if x > 0.0 && y > 0.0 => 1,
        Point { x, y } if x < 0.0 && y > 0.0 => 2,
        Point { x, y } if x < 0.0 && y < 0.0 => 3,
        Point { x, y } if x > 0.0 && y < 0.0 => 4,
        _ => 0,
    }
}

現在の制限事項

  • let バインディングでのタプル分解(let (a, b) = pair)はまだサポートされていません。代わりに match を使用してください。
  • 深くネストされた構造体に対するネストされたパターンマッチングは動作しますが、すべてのケースで網羅性検査が完全ではありません。
  • Orパターン(A | B => ...)はパースされますが、カバレッジ検査はまだ成熟途上です。