Muh*_*wil 5 generics methods types dart flutter
你好,当我使用这个通用方法时,我收到此错误
无法将“num”类型的值分配给“T”类型的变量。尝试更改变量的类型,或将右侧类型转换为“T”。
这里有什么错误
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);
}
Run Code Online (Sandbox Code Playgroud)
lrn*_*lrn 15
这里的问题是 Dart 2.12.0 中引入的新 Null Safety 功能从语言中删除了隐式向下转型。
如果res具有类型Twhere T extends num,则该操作res + something具有静态类型num。我们唯一知道的T是它实现num并num.operator+返回num。但是,num不可分配给,T extends num因为后者是前者的子类型(T可能是int,并非所有num值都可分配给int)。因此,您需要显式强制转换才能使分配有效:
res = (res + list[i]) as T;
Run Code Online (Sandbox Code Playgroud)
就是这样的演员阵容。如果你只写res = res + list[i] as T;, 的优先级as意味着它与上面的强制转换相同。在 Dart 2.10.x 中,它无需显式强制转换即可工作,因为该语言为您插入了隐式强制转换。
如果你写res += list[i] as T;它,则意味着res = res + (list[i] as T);这是不必要的转换,因为list[i]已经有 type T,并且不会转换加法的结果。
这不会一直失败的原因int res = ...; res = res + otherInt;是,语言规范会进行int.operator+特殊处理(以及一些类似的整数运算符)并识别结果何时为整数,即使+运算符的返回类型是num。这种特殊情况不适用于T extends num.
这似乎是 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);
}
Run Code Online (Sandbox Code Playgroud)
我收到你提到的错误:
main.dart:14:9: Error: A value of type 'num' can't be assigned to a variable of type 'T'.
res = res + list[i];
^
Run Code Online (Sandbox Code Playgroud)
但是,如果我在 Dart 2.10.5 中运行相同的代码,程序编译并运行不会出现问题,并且我会得到以下打印输出:
6.5
6
6.6
Run Code Online (Sandbox Code Playgroud)
我最好的猜测是,涉及类型参数的类型推断存在问题List。它似乎没有采用传递给 的实际类型参数sums,而是将类型限制num作为其推断类型。结果,类型系统发现您将 a 添加num到 a T extends num,然后将其分配给后者。(解释一下,想象T一下int。Anum加 anint会得到 a num。然后尝试将其分配给 an 会int导致类型错误,因为对于所有类型系统而言,num实际上可能是 a double。)
无论如何,一旦您执行错误建议的操作并将元素转换为listto ,错误就会消失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
Run Code Online (Sandbox Code Playgroud)
但有趣的是,无论转换如何,使用加法赋值都会导致相同的错误:
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];
// ^
Run Code Online (Sandbox Code Playgroud)
编辑:我已在 Dart SDK Github 页面上提交了有关此主题的问题。
编辑 2:事实证明这不是一个错误,而是作为 2.12 的一部分对 Dart 进行有意更改的结果。详情请参阅Irn的回答。
| 归档时间: |
|
| 查看次数: |
20950 次 |
| 最近记录: |