我是Dart的新手,它尝试使用答案here来实现List
的类,并尝试使用文档here对这些对象的列表进行排序。我删除了大部分代码以发布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();
}
以问题行运行会导致异常(未捕获的异常:TypeError:闭包“ Forecaster_tabulate_closure”:类型“(动态,动态)=>动态”不是类型“(动态,动态)=> int”的子类型) )我不明白。如果我注释掉问题行,则TypeError
消失。 TypeError
是因为我在定义Transaction
时做错了吗?我正在尝试使用DartPad。
答案 0 :(得分:2)
我也是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
更改为显式类型的列表,然后键入{{1 }}没有触发自动完成,我的IDE认为类型是a.when
,而不是dynamic
。
答案 1 :(得分:1)
您的问题在于类型。代码:
var transactions;
Forecaster(){
this.transactions = new List<dynamic>();
}
void tabulate(){
transactions.sort((a,b) => a.when.compareTo(b.when));
首先声明transactions
具有类型dynamic
。
然后,使用一个推断为sort
类型的参数调用dynamic Function(dynamic, dynamic)
(因为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)
是动态调用。