メインコンテンツまでスキップ

Match 文

紹介

match 文は1つの値を複数のパターンと比較して分岐する制御文です。 if / else if チェーンよりも分岐の意図をより明確に表現する際に有用です。

現在のWaveのmatchは**ステートメント(文)**であり、値として直接評価される式の形はサポートされていません。 つまり、var x = match (...) { ... }のような形は使用できません。


基本文法

match (value) {
pattern1 => {
// 実行ブロック
}
pattern2 => {
// 実行ブロック
}
_ => {
// 基本ブロック
}
}

文法規則:

  • ヘッダーはmatch (expr)の形を使用します。
  • 各armは{ ... }の形を使用します。
  • arm本文は必ず{ ... }ブロックである必要があります。
  • arm間には改行を使っても良く、,または;を区切りとして使っても良いです。

パターンの種類

現在サポートされているパターンは以下の3種類です。

  1. 整数リテラルパターン
0 => { ... }
1 => { ... }
42 => { ... }
  1. 識別子パターン
Off => { ... }
On => { ... }

識別子パターンはenumバリアントのような整数定数として解釈可能な値を対象に使います。

  1. ワイルドカードパターン(_)
_ => { ... }

どのパターンにもマッチしなかったときに実行されるデフォルトのarmです。


マッチ対象タイプ

現在の実装基準で、matchの対象値は整数系/enum系でなければなりません。 文字列、浮動小数点、構造体などはmatchの対象として使用できません。


例1: 整数分岐

fun classify_num(v: i32) -> i32 {
var result: i32 = -1;

match (v) {
0 => {
result = 10;
}
1 => {
result = 20;
}
_ => {
result = 99;
}
}

return result;
}

例2: enum分岐

enum Mode -> i32 {
Off = 0,
On = 1,
Unknown = 2
}

fun classify_mode(m: Mode) -> i32 {
match (m) {
Off => {
return 1;
}
On => {
return 2;
}
_ => {
return 3;
}
}
}

動作規則

  • switch系と同様に一致する1つのarmのみ実行されます。
  • 自動fallthroughはありません。
  • _ armは最大1回のみ使用できます。
  • _ armがなくても文法上許可されています。 (一致するarmがない場合は、何のarmも実行されません)

注意事項

  1. 重複ケース禁止
  • 同じケースを重複して宣言するとコンパイルエラーが発生します。
  1. _重複禁止
  • _ armを2回以上宣言することはできません。
  1. armブロック必須
  • =>の後には必ず{ ... }ブロックである必要があります。
  1. パターンは定数である必要があります。
  • 識別子パターンは整数定数/列挙体バリアントとして解釈可能な値のみを使用してください。

要約

Waveのmatchは整数/列挙体分岐に最適化されたステートメント制御文です。 => + ブロック構造を使用し、ワイルドカード(_)を通して基本分岐を構成できます。

分岐ケースが増えるほどif / else ifより読みやすく、意図を明確に示すことができます。