【问题标题】:Dart generic function for Iterable<num>Iterable<num> 的 Dart 通用函数
【发布时间】: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]));
}

【问题讨论】:

    标签: dart generics iterable


    【解决方案1】:

    有两个问题:

    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)
      
    2. 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]));
      }
      

      【讨论】:

        猜你喜欢
        • 2021-08-17
        • 2021-09-15
        • 2021-09-25
        • 1970-01-01
        • 2021-09-30
        • 2020-12-02
        • 2012-01-04
        • 1970-01-01
        • 2018-11-01
        相关资源
        最近更新 更多