狐好きぷろぐらまー

狐好きプログラマーのブログです。

【Dart】拡張メソッドでFizzBuzzを書いてみた【Static Extension Methods】

こんにちは。 @pregum_foxです。

今回は拡張メソッドのメモです。

目次です。

背景

いつの間にかDart2.6.1がリリースされていました。
ついこの前までは、2.5.1を使ってrxdartやflutter等を触っていましたが開発スピードが早くついていけない為、諸先輩方の記事で勉強させてもらいながらゆっくり勉強しています。

こちらの記事を見る限り、Dart2.6.0からStatic Extension Methods、拡張メソッドが追加されたようで、C#の拡張メソッドの様に書けるようになりました。

また確定ではないみたいですが、次のrxdart0.23.0で現在Observable<T>クラス内に定義されている変換系のオペレータが拡張メソッドに変更されるみたいです。
https://github.com/ReactiveX/rxdart/releases/tag/0.23.0-dev.1

というわけで、拡張メソッドの理解の為に拡張メソッドを使用してFizzBuzzを書いてみました。

こちらのページに構文が記載されていたので参考にしました。

FizzBuzz

以下に拡張メソッドで書いたFizzBuzzを示します。

dartのバージョンは2.6.1で試しました。 以下のコードはdartpadで試すことができます。

main() => extensionSample();

void extensionSample() {
  // 明示的に拡張メソッドを呼び出す
  ObjectExtension('fizz buzz サンプル').echo();

  // callが呼ばれる
  for (var val in 1(20)) {
    if (val.isFizzBuzz) {
      'fizzbuzz'.toUpperCase().echo();
    } else if (val.isFizz) {
      'fizz'.toUpperCase().echo();
      continue;
    } else if (val.isBuzz) {
      'buzz'.toUpperCase().echo();
    } else {
      val.echo();
    }
  }
}

extension FizzBuzzExtension on int {
  bool get isFizz => this % 3 == 0;
  bool get isBuzz => this % 5 == 0;
  bool get isFizzBuzz => this % 3 == 0 && this % 5 == 0;
}

extension ObjectExtension on Object {
  void echo() => print(this);
}

extension Tricky on int {
  Iterable<int> call(int to) =>
      Iterable<int>.generate(to - this + 1, (i) => i + this);
}
// 実行結果
// fizz buzz サンプル
// 1
// 2
// FIZZ
// 4
// BUZZ
// FIZZ
// 7
// 8
// FIZZ
// BUZZ
// 11
// FIZZ
// 13
// 14
// FIZZBUZZ
// 16
// 17
// FIZZ
// 19
// BUZZ

という感じです。

上記以外に、演算子(+, -, /, *等)や列挙型、抽象クラスに対しても拡張メソッドを追加することができるみたいです。

拡張メソッドを使用すると、Iterable<T>にオレオレLINQが追加できたり、StreamやSinkにユーティリティメソッドを追加など面白そうな使い道ができそうです。

ここまで読んで頂きありがとうございました。

参考サイト