Dart为什么不能推断List.fold()的类型?

时间:2019-01-26 14:56:53

标签: dart flutter type-inference

我正在Dart 2.1.0中尝试List.fold()

void main() {
  final a = [1,2,3];
  print(a.fold(0, (x,y) => x + y));
}

返回错误:

  

错误:未为类'dart.core :: Object'定义方法'+'。

     

尝试将名称更正为现有方法的名称,或定义一个名为“ +”的方法。

似乎无法推断x的类型为int,因此不知道如何在其中应用+

根据method specx应该具有与初始值0相同的类型,初始值显然是int为什么Dart不能推断出来?

我可以通过显式提示类型使其工作:

void main() {
  final a = [1,2,3];
  print(a.fold<int>(0, (x,y) => x + y));
}

但是我对Dart无法为我推断出这一点感到失望。在大多数其他情况下,其类型推断似乎更强。

1 个答案:

答案 0 :(得分:2)

Dart类型推断按预期工作:

void main() {
  final a = [1,2,3];

  var sum = a.fold(0, (x,y) => x + y);
  print(sum);
}

它在您的示例中失败的原因是因为类型推断结果取决于对表达式求值的上下文:

print(a.fold(0, (x,y) => x + y));

引发错误,因为print参数应该是Object:推断使用Object来填充fold的泛型T类型参数`:< / p>

T fold <T>(T initialValue, T combine(T previousValue, T element)) :

要验证此假设,请执行以下操作:

void main() {
  final a = [1,2,3];

  Object obj = a.fold(0, (x,y) => x + y);
}

引发完全相同的错误。

带走:

类型推断效果很好,但必须注意通用表达式的周围环境。

这是Dart的限制吗?

我不认为这种行为是对dart的限制,只是一种实现选择。

也许还有一些我不能说的合理的理论原因,但是我可以弄清楚一些原因。

考虑通用方法:

T fold <T>(T initialValue, T combine(T previousValue, T element))

及其用法:

Object obj = a.fold(0, (x,y) => x + y);

有两种方法可以推断T的类型:

  1. fold返回的值已分配给Object obj0Object,因为它是int,然后是{{1} }“解析为” T

  2. Object的第一个参数是fold,返回的值应该是int,而Objectint, 然后Object“解析为” T

Dart选择路径1:对于推断类型,它采用满足通用方法的“最广泛”(超类型)。

如果Dart实现路径2(推断的类型是“最近”类型)会更好吗?

在这种特定情况下,可能是,但随后某些情况将不适用于路径2。

例如,此代码段对路径2不满意:

int