Dart 中带有泛型的扩展方法:无法从方法返回动态类型的值

Extension methods with generics in Dart: Value of type dynamic can't be returned from method

鉴于此

extension<T> on List<T> {
  List<T> addAtTheEnd(T value) {
    return this.addAllAtTheEnd(<T>[value]);
  }

  List<T> addAllAtTheEnd(List<T> values) {
    return [
      ...this,
      ...values,
    ];
  }
}

在代码编辑器中,this.addAllAtTheEnd(<T>[value]) 带有下划线,意思是:

A value of type 'List<dynamic>' can't be returned from method 'addAtTheEnd' because it has a return type of 'List<T>'.

这对我来说听起来不合逻辑,因为 addAllAtTheEnd 方法没有编译错误,我在调用站点 (addAtTheEnd) 上明确定义了泛型的类型,并且我正在使用 this 以指示我正在调用该方法的类型。

为什么这不起作用,我怎样才能让它起作用?

是的,省略 this 即可解决,就像评论中建议的 jamesdlin 一样。


我彻底测试过了,结果如下:

这样编译:

...
  List<T> addAtTheEnd(T value) {
    return addAllAtTheEnd([value]);
  }

不是:

...
  List<T> addAtTheEnd(T value) {
    final thiz = this;
    return thiz.addAllAtTheEnd([value]);
  }

因为等价于下面,这里的问题比较清楚:

...
  List<T> addAtTheEnd(T value) {
    final List thiz = this;
    return thiz.addAllAtTheEnd([value]);
  }

但是显式声明类型有效:

...
  List<T> addAtTheEnd(T value) {
    final List<T> thiz = this;
    return thiz.addAllAtTheEnd([value]);
  }

有趣的事实:如果启用了 lint 规则,dart linter 会抱怨解决方案,即 omit_local_variable_types

所以调用 this 的正确和显式用法如下:

...
  List<T> addAtTheEnd(T value) {
    // ignore: omit_local_variable_types
    final List<T> thiz = this;
    return thiz.addAllAtTheEnd([value]);
  }

如果您通过以下方式使用内联显式转换:


  List<T> addAtTheEnd(T value) {
    return (this as List<T>).addAllAtTheEnd([value]);
  }

您收到 unnecessary cast 的警告,自动修复很乐意帮助您将代码转换为不可编译的代码。