👌

【Flutter】Dart3 switch文のつまづきポイント3選

2023/07/15に公開

Dart3で導入されたswitch文。先日enumのextentionで使ってみました。つまづいたり気になったポイントがあったので紹介します。

switchのポイント

1 switchの中身は、入れ替えるだけじゃエラーになる
2 デフォルトケースは_
3 エラーが出るならpubspeck.yamlでSDKをチェック

はじめに

Dart公式複雑じゃないか?

switch文の書き方を探すのに、当初Dart公式ページを見ました。これがDart公式のコード例。

token = switch (charCode) {
  slash || star || plus || minus => operator(charCode),
  comma || semicolon => punctuation(charCode),
  >= digit0 && <= digit9 => number(),
  _ => throw FormatException('Invalid')
};

いやもっとシンプルなのにして欲しいですね。。。後で紹介するデフォルトケースも書かれているのですが、全然判別できません。他の記事を探しました。

TakehiroKATOさんの記事がわかりやすい

結果、たどり着いたのが、@TakehiroKATO(Takehiro Kato)さんの記事。
サンプルのコードがシンプルでとにかく分かりやすかったです。

以降、コードもこちらの記事内のものを、少し編集する形で使わせていただきます🙇🏻‍♂️
https://qiita.com/TakehiroKATO/items/f8ac420b439851f0c219

新しいSwitch文の書き方

では改めまして、新しいswitch文の書き方は次の通りです。

final selectedAnimalType = AnimalType.dog;
final hiragana = switch(selectedAnimalType){
  AnimalType.dog => 'いぬ',
  AnimalType.cat => 'ねこ',
  AnimalType.bird => 'とり',
};

アロー関数が入り、視覚的に条件分岐を捉えやすくなっていますね。

switch文とswitch式

@TakehiroKATO(Takehiro Kato)さんの記事によると、switchの書き方に関する呼び方は次のように分かれています。

  • これまでのswitchの書き方をswitch文
  • 新しいswitchの書き方をswitch式

なお、ここではそういった細かい話は苦手なので、ここでは割愛しますが、記事の中ではswitch文switch式を使い分けて記載しています。ここで覚えておくと読みやすくなるでしょう。

switch内の入れ替えだけではエラーになる

では、ここから実際のケースに基づき、気づいた点を紹介します。

switch文からswitch式に変更してみようと思うのですが、みなさんはどのようなケースでswitchを使っていましたか?

私の場合、よくあるのは、enumのextentsionにgetterとして使うケースでした。
以下、switch文でのサンプルコートです。

enum AnimalType{
  dog,
  cat,
  bird,
}

extension AnimalTypeExt on AnimalType{
 String get hiragana {
    switch(this){
    case this.dog:
     return 'いぬ';   
    case this.cat:
     return 'ねこ';
    case this.bird:
     return 'とり';
    }
  }
}

では、新しいSwitch式で書いてみましょう

enum AnimalType{
  (省略)
}
extension AnimalTypeExt on AnimalType{
 String get hiragana {
   return switch(this){
     AnimalType.dog => 'いぬ',
     AnimalType.cat => 'ねこ',
     AnimalType.bird => 'とり',
   };
  }
}

ちょっとだけスッキリし、コードが読みやすくなりましたね。
さて、注意点があります。switchの中身を書き換えるだけ、と思いきやそうではありません。switchの前にreturnがないとエラーになります。私はこの点でつまづきました。気をつけましょう。

とは言ったものの、アロー関数で書けばこの注意も実際のところ不要になります。
ではswitch式をアロー関数で書いて、もっとスッキリさせていきましょう。

enum AnimalType{
  (省略)
}

extension AnimalTypeExt on AnimalType {
  String get hiragana => switch (this) {
        AnimalType.dog => 'いぬ',
        AnimalType.cat => 'ねこ',
        AnimalType.bird => 'とり',
      };
}

デフォルトケースは'''_'''

デフォルトケースの書き方についても触れたいと思います。デフォルトケースの書き方はちょっと意外です。
単に_で表現します。

enum AnimalType{
  (省略)
}

extension AnimalTypeExt on AnimalType {
 String get hiragana => switch (this) {
        AnimalType.dog => 'いぬ',
        _ => '名前の知らない動物',
      };
}

これは見た目としてしっくりこないのですが、慣れが必要ですね。Dart公式のようにちょっと複雑に書いていくと、他の記号に紛れて見つけにくくなるのが難点かと思っています。

エラーが出る!? Pubscpec.yamlをチェック

ここまで書いてた内容はDartPadで問題なく動くことが確認できました。しかし、いざ実際のプロジェクトで使用使用しようとするとエラーが出ます。

そんなときはpubspec.yamlのenvironmentを見てください。

私の使用していたFlutter3.10.5は、Dartとしては3.0.5を使用しているとのことでした。しかし、pubspec.yamlは次のようになっておりました。

environment:
  sdk: '>=2.5.0 <3.0.0'

対象の範囲に含まれていませんね。
適当に上限値等を変更します。

environment:
  sdk: '>=3.0.0 <4.0.0'

これでエラーが解消されました。
エラーが出ているならpubspec.yamlを一度見てください。

まとめ

今回 調査するうちに色々発見があり、記事もだいぶ方向性を変え、修正しました。読みにくかったかもしれませんが、みなさんの参考になればと思います。
switch文スッキリしていいですね。私のように変なところでつまづかず、どんどん使っていきましょう🙋‍♂️

参考資料

https://qiita.com/TakehiroKATO/items/f8ac420b439851f0c219

Flutter大学

Discussion