こんにちは!Dartの奥深い世界へようこそ。
Flutterでのアプリ開発や、バックエンドでのDartスクリプト作成を楽しんでいますか?
今回は、Dart 3で導入された革命的な機能の一つである「switch式(Switch Expressions)」、そしてその中で複数の条件をスマートに束ねる「orパターン(`|`)」について、徹底的に解説していきますね。
「いくつかの条件のどれかに当てはまったら、この値を返したい!」という場面、日常のコーディングで本当によく遭遇しますよね。従来の `switch` 文や `if-else` の連打でコードが縦に長くなり、うんざりした経験はありませんか?
ここをクリアすれば、あなたのDartコードは一気に洗練され、他の開発者から「おっ、分かってるね!」と言われるような美しいものになりますよ。さあ、一緒にマスターしていきましょう!
—
1. 従来の `switch` 文の「冗長な悩み」
まずは、私たちがこれまでよく書いてきた従来の `switch` 文(あるいは `if-else` 連打)を思い出してみましょう。
例えば、「ユーザーの入力したステータスコードや曜日に応じて、出力メッセージを変えたい」というシチュエーションを想像してください。
// 従来の switch「文」のスタイル
String getDayType(String day) {
String result;
switch (day) {
case ‘土’:
case ‘日’:
result = ‘週末’;
break;
case ‘月’:
case ‘火’:
case ‘水’:
case ‘木’:
case ‘金’:
result = ‘平日’;
break;
default:
result = ‘無効な曜日’;
}
return result;
}
なんだか縦長で、`break` を書き忘れるミス(フォールスルーの罠)に怯えたり、変数をわざわざ宣言して代入しなきゃいけなかったり……。ちょっと面倒ですよね。
—
2. 救世主!Dart 3 の「switch式」と「orパターン(`|`)」
Dart 3では、言語のパラダイムが大きく進化し、`switch` が「文(Statement)」だけでなく「式(Expression)」としても書けるようになりました。
式になるということは、三項演算子のように「そのまま値を返す」ことができるということ。さらに、パイプ記号(`|`)を使って複数のパターンを1行で「or(または)」結合できるんです。
百聞は一見に如かず。先ほどの曜日判定を、Dart 3の `switch` 式で書き直してみましょう。
// Dart 3の switch式 + orパターン(|)
String getDayTypeModern(String day) => switch (day) {
‘土’ | ‘日’ => ‘週末’,
‘月’ | ‘火’ | ‘水’ | ‘木’ | ‘金’ => ‘平日’,
_ => ‘無効な曜日’, // どのパターンにも一致しない場合(デフォルト)
};
なんてスマートなんでしょう!
コードの行数が劇的に減っただけでなく、何よりも「何を判定して何を返しているのか」が視覚的に一目で入ってきますよね。
—
3. ここが本質:orパターン(`|`)の読み方と仕組み
この ` ‘土’ | ‘日’ => ‘週末’ ` という書き方、裏側ではどう評価されているのでしょうか?
イメージとしては、論理演算子の「OR(または)」と同じです。
- 「もし入力値が `’土’` または `’日’` ならば、右側の `’週末’` という値を矢印(`=>`)の先へ流し込む」
という動きをします。
脳内トレース用図解イメージ
[ 入力値: ‘土’ ]
│
▼
┌───────────┐
│ ‘土’ | ‘日’ │ ──(一致!)──> ‘週末’ を返す
└───────────┘
│ (不一致)
▼
┌───────────────┐
│ ‘月’|’火’|… │ ──> 次の条件へ…
└───────────────┘
上から順番にパターンマッチングが評価され、最初に一致した(マッチした)アーム(枝)の式がそのまま結果として評価されます。`break` を書く必要はもうありません。Dart VMが安全に、そして最適化されたジャンプテーブル等を構築して高速に処理してくれます。
—
4. 実用例:UIのステータス管理で輝くテクニック
実際のFlutterアプリ開発でも、この `|` 結合は大活躍します。
例えば、ネットワーク通信の状態(Status)に応じて、画面に表示するバッジの色やテキストを切り替える例を見てみましょう。
enum NetworkState { connecting, waiting, success, error, timeout }
String getStatusDescription(NetworkState state) => switch (state) {
// 待機系のステータスをまとめる
NetworkState.connecting | NetworkState.waiting => ‘読み込み中…’,
// 成功系
NetworkState.success => ‘完了しました’,
// エラー・タイムアウト系をまとめる
NetworkState.error | NetworkState.timeout => ‘通信エラーが発生しました’,
};
どうですか? 「似たような扱いにしたいステータス」を `|` でまとめることで、将来新しい状態が増えたときにも、どのグループに属するべきかを直感的に追加できるようになります。
—
5. 初学者が陥りやすい文法エラーと注意点
ここで、実際にコードを書くときにつまづきやすいポイントをいくつか先回りして解説しておきますね。
① `break` を書かない!
従来の `switch` 文の感覚が抜けないと、つい `=>` の代わりにコロン( `:` )を書きたくなったり、行末に `break;` を書きたくなったりします。
しかし、`switch` 式 ではアロー構文(`=>`)を使い、各パターンの終わりはカンマ(`,`)で区切ります。`break` は不要です。
② 網羅性チェック(Exhaustiveness checking)の罠
Dartの強力な機能に「網羅性チェック」があります。これは、「入力され得るすべてのパターンがカバーされているか」をコンパイラが厳しくチェックしてくれる仕組みです。
もし、すべてのパターンを網羅していない状態で、最後の `_`(デフォルトのワイルドカード)を書き忘れると、コンパイルエラーになります。
// ❌ コンパイルエラーになる例(すべてのStringを網羅していないため)
String getRank(int score) => switch (score) {
100 => ‘満点!’,
1 | 2 | 3 => ‘合格’,
// エラー: The type ‘int’ is not exhaustively matched by the switch cases.
};
// ⭕ 正しい例(`_` でそれ以外を必ずキャッチする)
String getRankSafe(int score) => switch (score) {
100 => ‘満点!’,
1 | 2 | 3 => ‘合格’,
_ => ‘不合格またはその他’, // 網羅性を担保する
};
コンパイラが「おい、100点と1, 2, 3点以外の数値が来たときの処理が抜けてるぞ!」と優しく(厳しく)教えてくれるので、バグの温床を未然に防ぐことができます。
—
まとめ
いかがだったでしょうか?
- Dart 3の `switch` 式を使えば、コードを極限までシンプルに、美しく書ける。
- 複数の条件分岐は、orパターン(`|`)でスマートに1行にまとめられる。
- アロー構文(`=>`)を使い、`break` は不要。
- ワイルドカード(`_`)で網羅性を必ず担保する。
ここをクリアできれば、あなたのDartの書き方は一段階上のプロフェッショナルな領域へとステップアップします。ぜひ明日のコーディングから、この `|` パターンをガンガン取り入れてみてくださいね。
あなたのDartライフが、より快適でエキサイティングなものになりますように!