Dart:同步生成器函数“延迟”生成结果的行为到底是什么?

森口万*_*万太郎 1 dart

https://dart.dev/guides/language/language-tour#generators

当您需要延迟生成值序列时,请考虑使用生成器函数。Dart 内置支持两种生成器函数:

如上所述,“惰性”对于同步生成器函数到底意味着什么?行为与正常功能有区别吗?

void main(){

  Iterable<int> list1 = naturalsTo(3);
  print(list1.toList());//[0, 1, 2]

  print(naturalsTo(3).toList());//[0, 1, 2]
}

Iterable<int> naturalsTo(int n) sync* {
  int k = 0;
  while (k < n) yield k++;
}

Iterable<int> naturalsTo2(int n){
  int k=0;
  List<int> resultList = [];
  for(k;k<n;k++){
    resultList.add(k);
  }
  return resultList;
}
Run Code Online (Sandbox Code Playgroud)

上面代码的结果都返回相同的列表,但我不确定它们的行为有何不同。

“懒惰”到底是什么意思?

jam*_*lin 5

惰性求值是一个通用术语,用于描述直到需要时才计算结果的行为。它推迟计算以避免计算结果不会被使用。

您的示例(即使在更正它以不在两种情况下调用相同的函数之后)也没有表现出差异。相反,请考虑以下情况:

  • 每次循环迭代都有一个可观察到的副作用。在下面的示例中,我们将使用print,但实际上,可观察到的副作用通常是每次循环迭代都需要一些可测量的时间。
  • 我们不需要迭代所有元素。
void main() {
  print(naturalsTo(3).take(2).toList());

  print(naturalsTo2(3).take(2).toList());
}

Iterable<int> naturalsTo(int n) sync* {
  int k = 0;
  while (k < n) {
    print(k);
    yield k++;
  }
}

Iterable<int> naturalsTo2(int n) {
  int k = 0;
  List<int> resultList = [];
  for (k; k < n; k++) {
    print(k);
    resultList.add(k);
  }
  return resultList;
}
Run Code Online (Sandbox Code Playgroud)

第一种情况(使用同步生成器)打印:

0
1
[0, 1]
Run Code Online (Sandbox Code Playgroud)

第二种情况(使用普通函数)打印:

0
1
2
[0, 1]
Run Code Online (Sandbox Code Playgroud)