dart 错误:名称“E”不是类型,因此不能用作类型参数,如何创建泛型函数?

kt06eoxx  于 2023-02-14  发布在  其他
关注(0)|答案(1)|浏览(145)

我正在尝试创建一个顶级函数:

Iterable<E> mapEnumerated<T>(Iterable<T> iterable, E Function<E>(int, T) fn) sync* {
  var index = 0;
  for (final item in iterable) {
    yield fn(index++, item);
  }
}

但是,它报告错误消息:The name 'E' isn't a type so it can't be used as a type argument..
然后,我尝试将其更改为以下内容,上面的错误消失了,我不知道为什么,但我仍然不能使用它:

Iterable mapEnumerated<T>(Iterable<T> iterable, E Function<E>(int, T) fn) sync* {
  var index = 0;
  for (final item in iterable) {
    yield fn(index++, item);
  }
}

void main() {
  List<String> strs = mapEnumerated([5, 6, 7], 
    (i, e) => (i + e).toString()
  ).toList();

  print(strs);
}

这将报告错误:The argument type '(dynamic, dynamic) → String' can't be assigned to the parameter type '<E>(int, int) → E'.
怎样才是正确的实施方式呢?
下面的代码可以工作,但它根本不是一个泛型函数:

Iterable<String> mapEnumerated(Iterable<int> iterable, String Function(int, int) fn) sync* {
  var index = 0;
  for (final item in iterable) {
    yield fn(index++, item);
  }
}

void main() {
  List<String> strs = mapEnumerated([5, 6, 7], 
    (i, e) => (i + e).toString()
  ).toList();

  print(strs);
}

参考:原始代码来自https://github.com/dart-lang/sdk/issues/32467,我只是不确定如何将其实现为泛型函数。

6rqinv9w

6rqinv9w1#

类型变量E仅在fn参数的函数类型中引入,因此在该参数之外不可用。
这里的fn函数被声明为接受泛型函数,因此不能用(i, e) => (i + e).toString)调用它,因为该函数本身不是泛型的。
您可以将函数重写为:

Iterable<E> mapEnumerated<T, E>(Iterable<T> iterable, E Function(int, T) fn) sync* {
  var index = 0;
  for (final item in iterable) {
    yield fn(index++, item);
  }
}

这在mapEnumerated函数上引入了E类型变量,因此可以在该函数的返回类型中使用它。

相关问题