【 Flutter 】Flutter を 基礎 から 学習 ( Dart編 ) part38 Dartの特徴

基礎 から 学ぶ Flutter 」という書籍で  学習 したことを ブログでアウトプットしていこうと思います。今回は Dart編 ( part38 )です。

前回

【 Flutter 】Flutter を 基礎 から 学習 ( Dart編 ) part37 Dartの特徴

同期ジェネレータ、残りの部分です。

Dartの特徴

同期ジェネレータ

同期ジェネレータの再起処理についてです。
yieldは再起しょりすると計算量が多くなってしまうようです。

// 再起で表現したパターン
Iterable<int> getRange(int start, int end) sync* {
  if(start <= end) {
      yield start;
    
      for (final val in getRange(start + 1, end)) {
        yield val;
      }
  }
}
void main()  {
  // フィルタ(where)をしようして偶数の値のみ抽出しています。
  //final numbers = getRange(1, 10).where((num) => num % 2 == 0);
  final numbers = getRange(1, 10);
  for (var val in numbers) {
    print(val);
  }
}

再起処理については理解しているつもりですが・・

yield*を使うと1度に1つの値としてIterabl全体を生成できます。

どういうことでしょう???

こちらのサイトでも同様の問題を挙げられていました。

Dart 2 Language Guide (cresc.co.jp)

以下の実装を・・・

Iterable naturalsDownFrom(n) sync* {
  if (n > 0) {
    yield n;
    for (int i in naturalsDownFrom(n - 1)) {
      yield i;
    }
  }
}
main() {
  var it = naturalsDownFrom(3).iterator;
  while (it.moveNext()) {
    print(it.current);
  }
}

以下のように修正すると問題を回避できるそうです。

Iterable naturalsDownFrom(n) sync* {
  if ( n > 0) {
    yield n;
    // 再起処理の場合はyield*を使用するということでOKですかね?
    yield* naturalsDownFrom(n-1);
 }
}
main(){
  var it = naturalsDownFrom(3).iterator;
  while (it.moveNext()) {
  print(it.current);
  }
}

最後に

数学は苦手なので「なるほど😆」とはいきませんが・・・

同期処理にて再起処理を行う場合はyield*を使用するということだけ覚えておきます!

今日はここまで!