Iterable<num> 的 Dart 通用函数

Posted

技术标签:

【中文标题】Iterable<num> 的 Dart 通用函数【英文标题】:Dart generic function for Iterable<num> 【发布时间】:2022-01-16 05:59:39 【问题描述】:

我正在学习 Dart 中的泛型,但无法使用以下示例。该函数采用任何类型的 num(int 或 double)的 Iterable 并返回其总和。我该如何解决这个问题?

N sum<N extends num, T extends Iterable<N>>(T numbers) 
  return numbers.reduce((acc, n) => acc + n);


void main() 
  print(sum([1, 2, 3]));

【问题讨论】:

【参考方案1】:

有两个问题:

    sum([1, 2, 3])List&lt;int&gt; 参数推断T,但它不直接约束N。如果没有约束,N 将被假定为num,调用将被推断为sum&lt;num, List&lt;int&gt;&gt;(因为List&lt;int&gt; 被认为是List&lt;num&gt; 的子类型)。你不需要这么多类型参数,而是应该使用:

    N sum<N extends num>(Iterable<N> numbers)
    

    accn 都是N 类型,所以acc + n 使用N.operator +。由于N 派生自num,因此N.operator + 必须符合num.operator +,这在静态上已知会返回num。但是,编译器无法推断返回的num 一定是N,因为这可能是不安全的向下转换。

    实际上,允许从num 派生的唯一类型是intdouble,它们都提供了对operator + 的覆盖,该覆盖返回自己的类型。因此,显式向下转换N.operator + 的结果应该是安全的,您可以使用以下方法修复静态类型错误:

      return numbers.reduce((acc, n) => (acc + n) as N);
    

【讨论】:

【参考方案2】:

你有两个选择:

//you have to specify types when calling this function(see example)
N sum<N extends num, T extends Iterable<N>>(T numbers) 
  return numbers.reduce((acc, n) => acc + n);


//you have to call cast() method
N sum2<N extends num, T extends Iterable<N>>(T numbers) 
  return numbers.cast<N>().reduce((acc, n) => acc + n);


void main() 
  print(sum<int, List<int>>([1, 2, 3]));//specify types
  print(sum2([1, 2, 3]));

【讨论】:

以上是关于Iterable<num> 的 Dart 通用函数的主要内容,如果未能解决你的问题,请参考以下文章

类型“ExpandIterable<InterfaceType, MethodElement>”不是“iterable”的“Iterable<MethodElementImpl>

“Iterable<Element> 不能转换为 List<Element>” - `List` 不是 `Iterable` 的一种吗?

参数类型“Iterable<Future<dynamic>>”不能分配给参数类型“Iterable<Future<news_item>>”

为啥 Kotlin Array<T> 不实现 Iterable<T>

Flutter List 不是“Iterable<dynamic>”类型的子类型

参数类型“List<Categories>”不能分配给参数类型“Iterable<Categories>”