这似乎是 Dart 2.12+ 的错误或被误解的功能。无论哪种情况,都值得在 Dart Github 页面上打开一个问题。
如果我在 2.12.0 中运行以下代码:
void main() {
final nums = [1, 2.0, 3.5];
final ints = [1, 2, 3];
final doubles = [1.1, 2.2, 3.3];
sums(nums);
sums(ints);
sums(doubles);
}
void sums<T extends num>(List<T> list) {
T res = list[0];
for (var i = 1; i < list.length; i++) {
res = res + list[i];
}
print(res);
}
我收到你提到的错误:
main.dart:14:9: Error: A value of type 'num' can't be assigned to a variable of type 'T'.
res = res + list[i];
^
但是,如果我在 Dart 2.10.5 中运行相同的代码,程序编译并运行没有问题,我得到以下打印输出:
6.5
6
6.6
我最好的猜测是,在涉及 List 的类型参数时,类型推断存在问题。它没有将实际类型参数传递给sums,而是将类型约束num 作为其推断类型。结果,类型系统会看到您将 num 添加到 T extends num,然后将其分配给后者。 (解释一下,假设T 是int。num 加上int 将导致num。尝试将其分配给int 会导致类型错误,因为对于所有类型系统知道,num 实际上可能是 double。)
无论如何,一旦您按照错误提示执行操作并将list 的元素转换为T,错误就会消失:
void sums<T extends num>(List<T> list) {
T res = list[0] as T;
for (var i = 1; i < list.length; i++) {
res = res + list[i] as T;
}
print(res);
}
// Prints:
//
// 6.5
// 6
// 6.6
不过,有趣的是,使用加法赋值会导致相同的错误,而不管转换如何:
void sums<T extends num>(List<T> list) {
T res = list[0];
for (var i = 1; i < list.length; i++) {
res += list[i] as T;
}
print(res);
}
// Prints:
//
// main.dart:14:9: Error: A value of type 'num' can't be assigned to a variable of type 'T'.
// res += list[i];
// ^
编辑:I've filed an issue for this topic on the Dart SDK Github page.
编辑 2:事实证明这不是错误,而是作为 2.12 的一部分对 Dart 进行的预期更改的结果。有关详细信息,请参阅 Irn 的答案。