Dart泛型扩展报错:返回类型'num'不符合闭包要求的'T'
Dart扩展中sum方法类型错误的原因与解决办法
问题代码
定义的扩展如下:
extension MyIterable<T extends num> on Iterable<T> { T sum() => reduce((v, e) => v + e); // Error }
运行时出现错误:
返回类型'num'不是闭包上下文所要求的'T'类型。
使用示例:
void main() { int a = MyIterable<int>([1, 2]).sum(); double b = MyIterable<double>([1.0, 2]).sum(); num c = MyIterable<num>([1.0, 2]).sum(); }
错误原因
Dart的类型系统中,num类的+运算符签名是num operator +(num other)——不管调用的是int还是double的+,编译器只能确定返回值是num类型,无法自动推断出具体的子类T(比如int或double)。
而Iterable.reduce方法要求回调函数的返回值必须是泛型类型T,但这里v + e的静态类型是num,和要求的T不匹配,因此编译器报错。
解决办法
可以通过类型转换将num类型的结果转为T,实际运行时,当Iterable的元素都是T类型时,v + e的结果必然是T(比如int+int返回int,double+double返回double),所以转换是安全的:
extension MyIterable<T extends num> on Iterable<T> { T sum() => reduce((v, e) => (v + e) as T); }
如果需要处理空集合的情况,可加上判断逻辑:
extension MyIterable<T extends num> on Iterable<T> { T sum() { if (isEmpty) throw StateError('无法对空集合求和'); return reduce((v, e) => (v + e) as T); } }
修改后,main函数中的三种使用场景都能正常运行。
内容的提问来源于stack exchange,提问作者iDecode
相关产品推荐
相关产品推荐

