"すべての分岐は、予測可能でなければならない。"
プログラミングにおける「分岐」は、最も古く、最も脆弱な構造のひとつである。
多くのバグは、「条件が抜けていた」「意図しない状態が混入していた」という分岐の曖昧さから生まれる。
Rustの match
は、この分岐を根底から再定義する。
それは「分岐のための構文」ではなく、**「状態を列挙し、必ず処理するための構造」**である。
この章では、Rustの match
に込められた構文的強制と設計哲学を深掘りする。
match
は「条件分岐」ではない、「網羅宣言」である
match status {
Status::Ok => println!("All good."),
Status::Error => println!("Something went wrong."),
}
この構文は、単に if-else
を置き換えたものではない。
Rustコンパイラは、Status
に定義されているすべてのバリアントが match
されているかを静的にチェックする。
未処理のパターンがある場合、コンパイルエラーになる。
// 仮にStatusにWarningが追加された場合、上記コードはコンパイルできなくなる
これは、分岐の自由ではなく、すべての可能性を“設計段階で定義しなければならない”という構文的強制である。
曖昧な分岐を“書けないようにする”という設計
Rustは、以下のような“ついうっかり”のロジックを許さない:
// JavaScriptの例(意図しないdefault漏れ)
switch (status) {
case "OK":
// ...
break;
// あれ? WARNINGの処理書いてなかった…
}
Rustではこのような設計の抜け漏れが発生し得ない。
すべてのケースが記述されるか、明示的に_ =>
で握りつぶされる。
match status {
Status::Ok => println!("OK"),
Status::Warning => println!("Warning"),
Status::Error => println!("Error"),
}
あるいは明確に意図を示す:
_ => println!("Unknown"),
この違いが、曖昧なプログラミングと、構造的設計との分水嶺である。
match
はデータを“破壊的に展開する”安全な構文
enum Command {
Add(i32, i32),
Subtract(i32, i32),
Quit,
}
fn execute(cmd: Command) {
match cmd {
Command::Add(a, b) => println!("Sum: {}", a + b),
Command::Subtract(a, b) => println!("Diff: {}", a - b),
Command::Quit => println!("Goodbye."),
}
}
ここで注目すべきは、match
が単に分岐しているのではなく、構造の中の値を安全に“展開”して扱っている点である。
構造体の分解と条件分岐を同時に行い、その整合性がコンパイル時に検証される。
条件を書くのではなく、「状態を定義する」構文
従来の if-else
構文では、「どの条件が成立するか」を書く。
だがRustの match
は、「状態がこうであるなら、こう処理する」という論理分岐ではなく状態定義なのだ。
「設計者が認識しているすべての世界」を、matchは明示させる。
これは構文でありながら、設計者の世界モデルの写像である。
if let と match:部分一致と全網羅の思想的違い
Rustには if let
という構文もある。
if let Some(value) = maybe {
println!("Value: {}", value);
}
これは「特定の分岐だけ扱いたい」というシンプルなケースで便利だが、
「他のケースを無視する」ことを意図的に表現する構文でもある。
対して match
は、すべての可能性と向き合う覚悟の構文である。
match式は“値を返す式”であり、副作用に頼らない
Rustの match
は式であり、値を返すことができる:
let result = match operation {
Op::Add => a + b,
Op::Sub => a - b,
Op::Mul => a * b,
};
これは、副作用として処理するのではなく、構造から値を得るという純粋性を表している。
構造が変わるたびに、出力される値が決まる。
それは、条件分岐ではなく“状態と値の写像関係”の宣言である。
結語:分岐の構文を設計の構造に変換したRustのmatch
Rustの match
は、「どれかに当たればよい」という発想を否定する。
それは、「すべてに対処しなければならない」という設計倫理を言語構文として強制する仕組みである。
そしてそのことが、コードの明快さ、将来の変更への強さ、エラー耐性の高さを生む。
"分岐を書くな、状態を定義せよ。それがmatchの本質である。"