尝试对自定义对象列表进行排序时出现 TypeError



我是 Dart 的新手,并试图使用此处的答案让一个类来实现List,并尝试使用此处的文档对这些对象的列表进行排序。我删除了大部分代码,以发布MWE:

import 'dart:collection';
class Transaction<E> extends ListBase<E>{
DateTime when;
Transaction(this.when);
List innerList = new List();
int get length => innerList.length;
void set length(int length){
innerList.length = length;
}
void operator[]=(int index, E value){
innerList[index] = value;
}
E operator [](int index) => innerList[index];
void add(E value) => innerList.add(value);
void addAll(Iterable<E> all) => innerList.addAll(all);
}
class Forecaster{
var transactions;
Forecaster(){
this.transactions = new List<dynamic>();
}
void tabulate(){
transactions.sort((a,b) => a.when.compareTo(b.when)); //problem line?
for(var d in transactions){
d.asMap().forEach((index,content){
int len = content.toStringAsFixed(2).length;
});
}
}
void forecast(var forWhen){
var first = new Transaction(DateTime.now());
first.addAll([5,9]);
transactions.add(first);
}
}
void main(){
Forecaster myTest = new Forecaster();
var dub = myTest;
dub..forecast(DateTime.now())
..tabulate();
}

使用问题行运行会导致异常(未捕获的异常:类型错误:闭包"Forecaster_tabulate_closure":类型"(动态,动态)=>动态"不是类型"(动态,动态)=> int"的子类型)我不明白。如果我注释掉问题行,TypeError就会消失。TypeError是因为我在定义Transaction时做错了什么吗?我正在尝试使用DartPad。

我也是 Dart 的新手,所以我的解释可能不是 100% 在钱上,但我相信,是的,主要问题是transactions的类型分配。我认为因为您将它初始化为 var,所以它很难推断出a.when的类型,这意味着它也不知道a.when.compareTo()的类型,并假设dynamic。 您正在将compareTo的输出馈送到List.sort()中,该需要匿名函数的int。因此,它想要一个int但得到dynamic的错误。

解决此问题的最简单方法是使用更显式的类型而不是 var 初始化事务:

List<Transaction> transactions;
Forecaster(){
this.transactions = new List<Transaction>();
}

另外,为了确认这是无法推断 compareTo 的返回类型的问题,我尝试保持您的代码不变,但明确将结果转换为 int,这也有效:

transactions.sort((a,b){
return (a.when.compareTo(b.when) as int);
});

注意:像上面这样的代码并使用大量的动态和变量通常不是Dart的好练习 - 你失去了拥有类型语言的很多好处。您可能还会注意到,当您键入 IDE 时,当您执行此类操作时,您不会自动建议的方法 - 例如,直到我transactions更改为显式类型的列表,键入a.when不会触发自动完成,并且我的 IDE 认为该类型是dynamic,而不是DateTime

您的问题在于类型。代码:

var transactions;
Forecaster(){
this.transactions = new List<dynamic>();
}
void tabulate(){
transactions.sort((a,b) => a.when.compareTo(b.when));

首先声明transactions具有类型dynamic。 然后你用一个推断为具有类型dynamic Function(dynamic, dynamic)的参数调用sort(因为在transactions类型中没有线索可以说其他

)。然而,transactions的实际运行时类型是List<Transaction>,这需要一个类型为int Function(Transaction, Transaction)的函数参数。类型dynamic Function(dynamic, dynamic)不是int Function(Transaction, Transaction)的子类型(返回类型必须是int的子类型才能出现这种情况),因此会出现运行时错误。

如果将transactions更改为具有类型List<Transaction>,则类型推断在到达函数文本时将有一个线索。它将推断(a, b) => a.when.compareTo(b.when)期望int Function(Transaction, Transaction)将具有该类型的上下文中。

即使您只是将transactions更改为List<dynamic>,它仍然有效,它只会使a.when.compareTo(b.when)成为动态调用。

最新更新