【问题标题】:Dart List.fold vs List.reduce type inferenceDart List.fold 与 List.reduce 类型推断
【发布时间】:2022-04-11 16:23:07
【问题描述】:
使用 Dart 2.14.2 我运行了以下代码
void main(List<String> args) {
var a = <int>[1, 2, 3];
final foldValue = a.fold(0, (previousValue, element) => previousValue + element);
final reduceValue = a.reduce((previousValue, element) => previousValue + element);
}
对于包含foldValue 的行,分析器给我以下错误:
Error: The operator \'+\' isn\'t defined for the class \'Object?\'.
没有给出包含reduceValue 的行的任何错误。
我的问题是:是什么让 List.fold 引发了这样的错误,而 List.reduce 却没有?
标签:
list
dart
reduce
static-analysis
fold
【解决方案1】:
List.fold 问题是众所周知的 Dart 类型推理算法的限制。
由于您没有向fold 提供类型参数,因此类型推断会推断每个参数的静态类型独立地,然后尝试将它们组合起来以找到fold 本身的有效类型参数。
这两个论点是独立推断的并且没有类型提示.
0 参数很简单,它的类型为 int。
(previousValue, element) => previousValue + element 函数更难。
该算法不知道第一个参数应该是什么类型。应该是T,fold的类型参数,但我们还不知道T。它不能使用主体,因为它不能在它有参数类型之前对主体进行类型分析(即使可以,也有许多参数类型会使主体有效;dynamic,@987654332 @、num 和 double 是潜在的候选对象,并且可以有更多的用户类型允许您将 int 添加到它们。)
在没有外部提示的情况下,类型推断使用顶级类型并获得(Object? previousValue, int element) => ...。然后它无法接受previousValue + element。
reduce 没有失败的原因是它拥有所有必要的信息。两个参数都必须具有类型int,即列表的元素类型。