match の基礎
match は YaoXiang において最も強力な制御フロー構造です。これは値の形状に基づいて、異なる処理パスを選択できます。他の言語の switch を使ったことがあるなら、match はその全面アップグレード版だと気づくでしょう。
基本構文
構文仕様における match 式の定義:
match Expr { MatchArm+ }
MatchArm : Pattern ('|' Pattern)* ('if' Expr)? '=>' Expr ','分解すると:
matchの後にマッチさせる値が続く{}内に1つ以上のマッチアーム(MatchArm)が含まれる- 各マッチアーム:パターンの後に
=>が続き、その後ろに結果式が続く - 各アームはカンマで終わる
最も単純な例:
number = 2
text = match number {
0 => "零",
1 => "一",
2 => "二",
}
print(text) // "二"match は式である
if と同様に、match も式である——値を計算して返します。すべてのマッチアームの戻り値の型は一貫している必要があります:
score = 85
grade = match score {
90..100 => "A", // 範囲パターン(上級コンテンツ)
80..89 => "B",
70..79 => "C",
60..69 => "D",
_ => "F", // ワイルドカード:残りのすべてにマッチ
}
print(grade) // "B"注意:範囲パターン
90..100などは上級コンテンツであり、パターン照合の上級編 で詳しく解説します。本章では基本パターンに焦点を当てます。
基本パターン
リテラルパターン
具体的な値でマッチさせます:
response = 404
message = match response {
200 => "OK",
301 => "Moved",
404 => "Not Found",
500 => "Server Error",
_ => "Unknown",
}
print(message) // "Not Found"識別子パターン
変数名でマッチした値をキャプチャします:
result: Result(Int, String) = ok(42)
description = match result {
ok(value) => "成功、値は: " + value.to_string(),
err(error) => "失敗、理由: " + error,
}
print(description) // "成功、値は: 42"ok(value) の value は識別子パターンです——ok にラップされた実際の値をキャプチャし、=> の後の式で使用できます。
ワイルドカードパターン
_ はワイルドカードで、任意の値にマッチします。通常は最後に配置し、フォールバックとして使います:
command = "exit"
action = match command {
"start" => "サービス起動",
"stop" => "サービス停止",
"restart" => "サービス再起動",
_ => "不明なコマンド: " + command,
}
print(action) // "不明なコマンド: exit"マッチは完全でなければならない
YaoXiang の match は、すべての可能なケースをカバーすることを要求します——コンパイラが一部の可能な値を見落としていることを発見した場合、直ちにエラーを報告します。これは match の安全性の表れです。
// このコードはコンパイルに失敗する
// value = true
// result = match value {
// true => "はい",
// // false ケースが欠落——コンパイルエラー!
// }
// 正しい——_ を使ってフォールバック
value = true
result = match value {
true => "はい",
_ => "いいえ", // _ で false も処理されることを保証
}有限のシナリオしかありえないと明確に分かっている場合(列挙型をマッチさせるなど)、コンパイラはすべてのバリアントがカバーされているかをチェックします。これはケースの書き忘れバグを防ぐ強力な武器です。
マルチパターンの組み合わせ
1つのマッチアームは | で区切ることで複数のパターンにマッチできます:
day = "sunday"
type = match day {
"monday" | "tuesday" | "wednesday" | "thursday" | "friday" => "平日",
"saturday" | "sunday" => "休日",
_ => "無効",
}
print(type) // "休日"マッチアームは順序通りに実行される
match は最初のアームからマッチを試み、最初にマッチに成功した分岐が有効になり、後ろは実行されません:
number = 5
result = match number {
_ => "その他", // ワイルドカードがすべてにマッチ、ここがマッチする
5 => "五", // 決して実行されない——上で既にマッチした
}
print(result) // "その他"この特性から、ワイルドカード _ を最後に配置するのは良い習慣です。
まとめ
| 要点 | 説明 |
|---|---|
| 構文 | match 値 { パターン => 式, ... } |
| 式 | match は値を計算し、すべての分岐の型が一致する |
| リテラルパターン | 具体的な値と精密にマッチ:200 => "OK" |
| 識別子パターン | 値を変数にキャプチャ:ok(value) => ... |
ワイルドカード _ | 任意の値にマッチ、フォールバックとして |
| 完全性 | すべての可能性をカバーする必要があり、コンパイラがチェック |
| マルチパターン | パターン1 | パターン2 => 式 |
| 順序実行 | 上から下へ、最初のマッチした分岐が有効 |
次のステップ:本稿では
matchの基本構文をカバーしました。上級パターン(ネストパターン、ガード式、構造体デストラクトなど)は パターン照合の上級編 を参照してください。
