Dart中的接口约束

时间:2014-08-19 20:23:15

标签: types casting dart

我将我的一个库从Ruby移植到Dart以获得对该语言的感觉,并且到目前为止事情进展顺利。语言感觉还可以,并没有太多粗糙的边缘。现在假设Dart是可选的类型,我可以给一切动态类型,并称它为一天,但这将是毫无意义的。所以我一直在尽可能地添加类型,但有几个地方我无法弄清楚该做什么。基本问题很简单。我正在处理基本上具有以下接口的对象

abstract class Indexable {
  Matchable operator [](int index);
}

abstract class Matchable {
  bool operator ==(dynamic other);
}

现在几乎所有东西都支持Matchable,但并不是所有东西都支持Indexable,尽管理论上很多东西都可以这样做。做明显的事情并不奏效。我无法使用as进行类型转换,因为我的测试表明,当我尝试将它们转换为String时,ListIndexable都会抛出异常。我能想到的其他解决方案是包装和反射,但两者都感觉像黑客并添加了一大堆不必要的样板,因为StringList已经实现了相关的运算符。

用例I的一些伪代码我想象

List<Matchable> matches(Indexable sequence, List<Matchable> matchers) {
  int index = 0;
  Matchable element;
  List<Matchable> accumulator = [];

  while ((element = sequence[index++]) != null) {
    if (matchers.any((m) => m == element)) {
      accumulator.add(element);
    }
  }

  return accumulator;
}

1 个答案:

答案 0 :(得分:2)

如果要对不与其中的操作共享接口的类使用“公共”操作,则需要使用dynamic作为类型,或者在使用它的地方进行动态类型检查{ {1}}。

Dart曾经有一个名为if (x is String) something(x[index]); else if (x is List) ...的类型,其中Sequence<T>T operator[](int index)为接口。之所以被删除,是因为我们觉得它没有自重。实际上只有两个实现,int get lengthList,它更像是一个偶然发生匹配的事故 - 使用String上的[]运算符并不是真的值得推荐,因为它打破了代理对

在你的情况下,我只使用List for Indexable,并忽略String恰好也是Indexable,除非原始程序依赖于它。