Dartのパターンマッチング:なぜ「失敗」の扱いで運命が変わるのか?
こんにちは。Dartの深淵を覗く旅へようこそ。
Dart 3で導入されたパターンマッチングは、単なるシンタックスシュガーではありません。これはDartが「宣言的で堅牢なデータ処理」へ進化するための大きな転換点です。
今日は、多くの開発者が最初の壁としてぶつかる「パターンマッチングの失敗(マッチ失敗)」が、`if-case`と`switch式`でどう異なるのか、その根本的な挙動を紐解いていきましょう。ここを理解すれば、コードの安全性が劇的に変わります。
—
1. パターンマッチングの「失敗」とは何か?
まず、大前提の話をしましょう。Dartのパターンマッチングにおける「失敗」とは、例外(Exception)が投げられることではありません。「提示されたデータ構造とパターンが一致しなかった」という単なる事実です。
- `if-case`の挙動: 「失敗?なら次へ行こう(無視)」
- `switch式`の挙動: 「失敗?それはプログラムの設計漏れだ(例外)」
この「失敗に対する態度の違い」を理解することが、バグを未然に防ぐ鍵になります。
—
2. if-case:優しく見逃す「フィルター」
`if-case`は、特定のパターンに合致する場合のみ処理を実行する「フィルター」です。マッチしなくても、コードはただ次の行へ流れていくだけです。
void processValue(dynamic input) {
// inputがString型かつ、”admin”という値なら処理
if (input case ‘admin’) {
print(‘管理者権限を確認しました’);
}
// マッチしなくてもエラーにはならず、ただスルーされる
print(‘次の処理へ進みます’);
}
ここがポイント:
`if-case`は「マッチしたら嬉しいけれど、マッチしなくても困らない」というオプション的な処理に適しています。
—
3. switch式:厳格に守る「ガード」
一方、`switch式`は「網羅性(Exhaustiveness)」を重視します。すべての可能性をカバーすることをコンパイラが強制します。
String getRoleDescription(String role) {
return switch (role) {
‘admin’ => ‘システム管理者’,
‘user’ => ‘一般ユーザー’,
// ‘guest’ など、他の値が来た場合に備えて ‘_’ (ワイルドカード) が必須!
_ => ‘未知のユーザー’,
};
}
もし網羅性を忘れると…?
コンパイラが「残りのケースが考慮されていません!」とコンパイルエラーを出します。これがDartの強力な「Null安全」に通じる静的解析の魔力です。`switch式`は「考えられるすべての場合に対処した」という証明がない限り、実行を許さないのです。
—
4. なぜこの違いが重要なのか?(陥りやすい罠)
初心者が最もハマりやすいのは、「`switch式`を使っているのに、途中で失敗してプログラムが止まってしまう」というケースです。
例えば、以下のようなコードを書いてしまったとしましょう。
// コンパイルエラーになる例
String status = ‘unknown’;
final result = switch (status) {
‘active’ => ‘稼働中’,
‘inactive’ => ‘停止中’,
// ここで’unknown’が来たときの処理がないため、コンパイルエラー!
};
「例外を投げたくないから」と適当に書くのではなく、「想定外のデータが来たときにどう振る舞うべきか」を強制的に考えさせられる。これが`switch式`の最大のメリットです。
—
5. まとめ:使い分けの指針
ここをマスターすれば、もうパターンマッチングで迷うことはありません。
| 特徴 | if-case | switch式 |
| :— | :— | :— |
| 失敗時の挙動 | 無視して次へ行く | コンパイルエラー(網羅性が必要) |
| 主な用途 | 特定条件の抽出、ガード節 | 値の変換、状態遷移の明示 |
| 安心感 | 緩やか(柔軟) | 厳格(安全) |
- 「とりあえず特定の条件だけ拾いたい」なら `if-case`。
- 「入力値に対して必ず何らかの結果を返したい」なら `switch式`。
Dartは、あなたが書いたコードが「どう実行されるか」をコンパイル時にすべて計算しています。`switch式`を使うときは、「すべての道筋を把握している」という自信を持つこと。それが、一流のDartエンジニアへの第一歩ですよ。
さあ、次はあなたのプロジェクトで、より安全でクリーンなコードを書いてみてください。応援しています!