【问题标题】:How to specify generic type such that we can use some operation on the generic type in Flutter?如何指定泛型类型以便我们可以在 Flutter 中对泛型类型进行一些操作?
【发布时间】:2021-01-26 06:30:02
【问题描述】:

例如,我希望<T extends type> 可以这样工作:

Class Parent {
  String data;
  Parent({ this.data });
}

Class Child extends Parent {
  Child({ this.data }) : Parent(data: data);
  void showData() { print(data); }
}

T wrapper<T extends Parent>(String value) {
  var result = T(data: value);
  return result;
}

void main() {
  var trial = wrapper<Child>("Hello world");
  trial.showMessage(); // print "Hello world"
}

但事实证明它给了我var result = T(data: value); 的错误,说 T 不是函数。当我指定 时,我希望 T 可以像 Parent 类一样操作,如果我像 Child 一样提供它的后代,则完成的操作将改为 Child。但是构造函数会以任何一种方式工作,因为 T 扩展了 Parent。这样的事情可能吗?

【问题讨论】:

标签: flutter generics


【解决方案1】:

构造函数不被继承。你已经知道了,因为你自己在你的子类中写了一个,它只用相同的参数调用基类。

也可以编写一个不同的构造函数。所以“X extends Y”说了很多关于 X 的内容,但它并没有说明 X 的构造函数的外观(或者它是否有一个在该范围内可访问的构造函数)。因此,当您将泛型指定为“扩展 Y”时,构造函数调用不在您可用的属性中,因为 Y 完全无法确保它的所有派生都遵循特定的构造方法。

不同的语言以不同的方式处理“但是我如何构造我的泛型类型的新实例”的问题,但基本概念对于几乎所有泛型概念都是通用的,其中泛型代码在知道具体代码之前就已编译处理的所有 T 的类型。构造函数在大多数 OOP 语言中都不会被继承,因此即使 Y 有它,也不能保证任何“X 扩展 Y”都存在。

当您将所有代码都放在一个编译单元中时,可能很容易被忽略。编译器应该能够弄清楚,对吧?但是您的代码可能不会在单个编译单元中

代码库一:

Class Parent {
  String data;
  Parent({ this.data });
}

T wrapper<T extends Parent>(String value) {
  var result = T(data: value);
  return result;
}

此时,编译器不知道“子”可能是什么样子。它不可能确定将在 Future 中使用的子类有这样的构造函数。

代码库 2:

Class Child extends Parent {
  Child({ this.data }) : Parent(data: data);
  void showData() { print(data); }
}

void main() {
  var trial = wrapper<Child>("Hello world");
  trial.showMessage(); // print "Hello world"
}

现在,在这一点上,编译器可以计算出它给出的程序实际上可以工作。泛型的一些概念就是这样做的,在泛型无法编译成独立库的情况下,它们总是作为源代码出现,因为只有生成可执行文件的最终编译器才能确定它是否适用于特定的类。颤振不这样做。 Flutter 需要泛型本身对给定的约束有效。

所有较新语言版本的泛型都遵循事先了解约束并只允许代码在这些约束内运行的路径。而且我认为这很好,因为虽然它有缺点,但它为错误或神秘的错误消息留下的空间更少。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-08-05
    • 2011-12-11
    • 2019-11-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-06-09
    相关资源
    最近更新 更多