プログラミング

Rust の match 構文ガイド

match は Rust の強力で柔軟な制御構造であり、複数のパターンに基づいて値を評価するために使用されます。これは、特にエラーハンドリングや複雑な条件分岐で非常に役立ちます。この記事では、Rust の match 構文の基本から応用までを完全に解説します。

match の基本構文

match は、値をパターンに照らして評価し、それにマッチしたブロックを実行します。基本的な構文は次のようになります。

rust
match 値 { パターン1 => 式1, パターン2 => 式2, _ => 式3, // デフォルトの場合 }

ここで、 は評価される対象の変数で、パターン はその値が一致するかどうかを確認する条件です。_ は「デフォルト」を意味し、他のすべてのパターンが一致しない場合に使用されます。

match の例

次に、match の基本的な使用例を見てみましょう。

rust
let number = 3; match number { 1 => println!("One"), 2 => println!("Two"), 3 => println!("Three"), _ => println!("Other"), }

このコードでは、number3 であるため、"Three" が出力されます。match は、最初に一致するパターンを見つけると、そこで評価が終了します。

複数のパターンを使う

match では、複数のパターンを同時に扱うことができます。これにより、同じ処理を複数の条件に対して適用することができます。

rust
let number = 5; match number { 1 | 2 | 3 => println!("Small number"), 4 | 5 | 6 => println!("Medium number"), _ => println!("Large number"), }

ここでは、123 のいずれかに一致する場合は “Small number” が出力され、456 のいずれかに一致すれば “Medium number” が出力されます。

ガード条件を使う

match の各パターンには、条件を追加して細かい制御を行うこともできます。これを「ガード条件」と呼びます。ガード条件は、if を使ってパターンに追加することができます。

rust
let number = 7; match number { n if n < 5 => println!("Small"), n if n >= 5 && n < 10 => println!("Medium"), _ => println!("Large"), }

この例では、n if n < 5 のように、特定の条件を付けてパターンをより詳細に制御しています。

Option 型と match

Rust では、Option 型を使用して値が存在するかどうかを表現します。この型は、Some(T)None の2つのバリアントを持っています。matchOption 型の値を操作する際に非常に有用です。

rust
let some_number = Some(10); match some_number { Some(n) => println!("The number is {}", n), None => println!("No number"), }

ここでは、some_numberSome(10) であるため、"The number is 10" と出力されます。もし None だった場合、"No number" が出力されます。

Result 型と match

Result 型は、操作が成功した場合と失敗した場合を表現するために使用されます。Ok(T)Err(E) の2つのバリアントがあり、これも match を使って処理できます。

rust
let result: Result<i32, &str> = Ok(5); match result { Ok(value) => println!("Success: {}", value), Err(error) => println!("Error: {}", error), }

この例では、resultOk(5) であるため、"Success: 5" が出力されます。もし Err だった場合、そのエラーが処理されます。

match と型の一致

Rust の match はパターンマッチングの精度が高いため、型の一致も厳密に行われます。これにより、予期しないバグを防ぐことができます。例えば、次のコードでは型が一致しないためコンパイルエラーが発生します。

rust
let number = 3; match number { 1 => println!("One"), "three" => println!("Three"), // コンパイルエラー _ => println!("Other"), }

この場合、"three" は文字列型ですが、number は整数型であるため、コンパイルエラーが発生します。

match のデストラクチャリング

match では、構造体や列挙型などをデストラクチャリングして、内部の値にアクセスすることができます。例えば、タプルや構造体を使ったパターンマッチングが可能です。

rust
let point = (3, 4); match point { (0, 0) => println!("Origin"), (x, 0) => println!("On the X axis: {}", x), (0, y) => println!("On the Y axis: {}", y), (x, y) => println!("Point at ({}, {})", x, y), }

このコードでは、point(3, 4) であるため、"Point at (3, 4)" と出力されます。

終わりに

match は Rust の中でも非常に強力で多用途に使える構造です。シンプルな条件分岐だけでなく、複雑なパターンマッチングやデストラクチャリングを活用することで、コードの可読性と保守性を向上させることができます。OptionResult 型との組み合わせは、エラーハンドリングを効率的に行うための強力な手段となります。

Rust の match は、他の多くのプログラミング言語の switchif よりもはるかに強力で柔軟な制御構造を提供しており、その使い方をマスターすることで、より洗練された Rust コードを書けるようになります。

Back to top button