我很难理解DART中的斐波纳契代码是如何工作的.

void main() async {
  List<BigInt> lista = [];
  final start = DateTime.now();
  finobacciPOC(lista, BigInt.from(15000), BigInt.zero, BigInt.one);
  print('lista');
  final time_exec = start.difference(DateTime.now());
  print("Calculate in time ${time_exec}");
}

void finobacciPOC(
    List<BigInt> listResult, BigInt total, BigInt start, BigInt end) async {
  BigInt sum = start + end;

  await Future.delayed(Duration(microseconds: 1));

  listResult.add(sum);
  total = total - BigInt.one;

  if (total == BigInt.zero) {
    print(listResult);
    return;
  }

  finobacciPOC(listResult, total, end, sum);
}

只有当您保留延迟的 routine 时,代码才有效(以防您想要生成15000个序列).如果删除延迟,将显示溢出错误.

我想了解这个场景是如何运作的.

推荐答案

之所以"有效",是因为您的方法是async,而不是等待隐式返回的Future.这意味着您当前的代码不会真正向调用堆栈添加任何内容,因 for each finobacciPOC都将"独立"运行,因为您正在进行的递归调用从不等待返回的Future.

查看您的代码的另一种方法是,我删除了await,并将其转换为您的代码的实际功能:

void finobacciPOC(
    List<BigInt> listResult, BigInt total, BigInt start, BigInt end) {
  BigInt sum = start + end;

  Future.delayed(Duration(microseconds: 1)).then((_) {
    listResult.add(sum);
    total = total - BigInt.one;

    if (total == BigInt.zero) {
      print(listResult);
      return;
    }

    finobacciPOC(listResult, total, end, sum);
  });
}

这里变得更加清楚,我们的调用堆栈上实际上没有递归调用,因为对finobacciPOC的调用将在从Future.delayed创建一个新的Future之后立即结束,这将在所提供的Duration个时间过go 后在事件队列上生成一个新事件.

例如,如果您更改您的方法,使其现在指定返回的Future,并使其成为递归调用:

Future<void> finobacciPOC(
    List<BigInt> listResult, BigInt total, BigInt start, BigInt end) async {
  BigInt sum = start + end;

  await Future.delayed(Duration(microseconds: 1));

  listResult.add(sum);
  total = total - BigInt.one;

  if (total == BigInt.zero) {
    print(listResult);
    return;
  }

  await finobacciPOC(listResult, total, end, sum);
}

它将开始崩溃,并出现堆栈溢出错误,因为这一更改实际上意味着我们在播放中再次有了调用堆栈.

如果我们希望给定的调用方finobacciPOC确切地知道方法何时完成运行,并且listResult实际包含结果,则需要进行此更改.

例如,在你的代码中,你实际上不知道finobacciPOC是什么时候完成的,这也意味着你对花费时间的计算是错误的.

Dart相关问答推荐

为什么在穷举switch 表达式中需要显式向下转换?

观察对象的状态

那么在 Flutter 中缓存最简单的方法是什么?

如何计算列表中元素的出现次数

表单的 TextFormField 中的多个光标(cursor)

为什么这个文件会自动创建自己 generate_plugin_registrant.dart

如何在flatter中读取本地json导入?

Flutter/Dart Uri 没有在 URL 中转义冒号:

在字符串中查找字母 (charAt)

如何判断设备是否需要 SafeArea?

如何使用 Dart 和 web 以 60fps 的速度驱动动画循环?

我如何知道 websockets 的连接是否有效?

Dart,对泛型的限制?

`FutureOr` 的目的是什么?

dart中 library关键字的确切含义

启用空安全时,默认的List构造函数不可用.try 使用列表文字,List.filled或List.generate

GWT 与 Dart - 主要区别是什么? Dart 是 GWT 的潜在替代品吗?

是否可以在 Dart 中的一行上初始化列表?

何时在 Dart 中使用 part/part of 与 import/export?

List firstWhere Bad state: No element