August 10, 2023

Dart3のSwitchを使う

前回 はSealedクラスを使いましたが、今回はSwitchを使います。

Switch自体はDart3以前からありましたが、Dart3からは文から式に変わりました!
これはかなり嬉しい進化です。 書き方はKotlinっぽいですね。

今までは変数を定義して、パターンごとに代入の必要がありましたが、Dart3からは不要になります。
他にもいろいろなパターンマッチができるようになったので紹介します。

switch式

enum Color {
  red,
  yellow,
  blue,
  white,
  black,
}

final isPrimary = switch (color) {
  Color.red => true,
  Color.yellow => true,
  Color.blue => true,
  _ => false
};

OR

それぞれではなくて、ORでまとめても書けます

final isPrimary = switch (color) {
  Color.red || Color.yellow || Color.blue => true,
  _ => false
};

AND

文でも書けましたが、ANDもできます

final isRange = switch (value) {
  >= 0 && <= 10 => true,
  _ => false,
};

if-else

ANDとORが使えるのでif-elseにもなります
今まではこのif-elseを書くのは結構冗長だったのでスッキリ書けていい感じですね

final result = switch (value) {
  < 0 => 'negative',
  == 0 => 'zero',
  > 0 && < 11 => '1-10',
  >= 100 && <= 1000 => '100-1000',
  _ => 'other'
};

Match

型にもマッチするようになりました

List

listにもマッチします
さらに、マッチした値を変数に代入してスコープ内で参照もできます

List<String> list = ['foo', 'bar'];
switch (list) {
  case ['foo', final value]:
    print(value);
}

// bar

Record

Dart3から追加されたRecordにもマッチします

(int, String) record = (100, 'hoge');

switch (record) {
  case (int _, String value):
    print(value);
}

// hoge

when

マッチした後に、条件文も追加できるようになりました
Recordにマッチしたあとのnumberに制限をつけるとこうなります

(int, String) record = (100, 'hoge');

switch (record) {
  case (int number, String value) when number > 10:
    print(value);
}

// hoge

null check

null checkもできるようになりました この場合 s? を後に書くことはできないので注意してください

void hoge(String? maybeString) {
  switch (maybeString) {
    case var s?:
      print("not null!");
    case var s:
      print("null!");
  }
}

まとめ

全部は紹介しきれていませんが、Dart3でパターンマッチの構文がかなり強化されました。
KotlinやSwiftにある機能が順調に実装されてきている感じがします。
まだまだ、完全には使い切れていませんが、徐々に慣れていきたいと思います。

© AAkira 2023