【问题标题】:Switching on class type in Dart在 Dart 中打开类类型
【发布时间】:2015-03-20 23:31:42
【问题描述】:

我希望在 Dart 超类中编写一个函数,该函数根据实际使用它的子类采取不同的操作。像这样的:

class Foo {
  Foo getAnother(Foo foo) {
    var fooType = //some code here to extract fooType from foo;
    switch (fooType) {
      case //something about bar here:
        return new Bar();
      case //something about baz here:
        return new Baz();
    }
  }
}

class Bar extends Foo {}

class Baz extends Foo {}

我的想法是我有一些对象并且想要获得相同(子)类的新对象。

主要问题是fooType 应该是什么类型?我的第一个想法是符号,它会导致像case #Bar: 这样的简单案例语句,但我不知道如何用符号填充fooType。我能想到的唯一选择是做类似Symbol fooType = new Symbol(foo.runtimeType.toString()); 的事情,但我的理解是runtimeType.toString() 在转换为javascript 时将不起作用。你可以通过使用 Mirrors 来解决这个问题,但这意味着它是一个轻量级的库,所以这些不在桌面上。 Object.runtimeType 返回 Type 类的某些内容,但我不知道如何创建可用于 case 语句的 Type 实例。也许我错过了更适合此的 Dart 库的其他部分?

【问题讨论】:

  • 子类的特殊行为,取决于类:这听起来与虚函数旨在解决的问题完全一样。如何拥有:class Foo { Foo _createNew() => new Foo(); Foo getAnother(Foo foo) => foo._createNew(); },然后是 class Bar extends Foo { _createNew() => new Bar(); } 和类似的 Baz

标签: dart


【解决方案1】:

您可以在switch 中使用runtimeType

class Foo {
  Foo getAnother(Foo foo) {
    switch (foo.runtimeType) {
      case Bar:
        return new Bar();
      case Baz:
        return new Baz();
    }
    return null;
  }
}

case 语句中直接使用类名(AKA 类文字)。这给出了一个与所提到的类相对应的Type 对象。因此foo.runtimeType可以与指定的类型进行比较。

请注意,类文字中的you can not use generics for now。因此,case List<int>: 是不允许的。

【讨论】:

  • 太棒了!我不知道你可以使用这样的类名。我不得不说,这似乎有点像魔术。您能否详细解释一下这种用法是如何工作的(也许还有一般的 Type 类)?
  • 这不适用于ListMapSet 以及可能的其他人。
  • 我相信这个带有 runtimeType 的 switch case 语句会在pub build 上导致错误(-> 'case' 表达式类型 'TypeImpl' 会覆盖 'operator =='。)。将代码更改为字符串比较(foo.runtimeType.toString()case 'Bar')可以通过pub build
  • 这对性能有影响吗?还是可以安全使用?
  • @AlexandreArdhuin 这对我不起作用。以下示例打印“No match.B”。 dartpad.dartlang.org/2012b9264ee9ec79e8c9800d42d3fbef
猜你喜欢
  • 1970-01-01
  • 2014-02-06
  • 2017-09-22
  • 1970-01-01
  • 1970-01-01
  • 2021-11-05
  • 2020-01-31
  • 1970-01-01
  • 2020-03-19
相关资源
最近更新 更多