【问题标题】:Defining a type to be a `Comparable` in Dart在 Dart 中将类型定义为“Comparable”
【发布时间】:2018-06-29 15:06:03
【问题描述】:

这个问题可能源于对 Dart 中的 OOP 理解不足,但无论如何:

我一直在从事一个项目,我的一个基类从dart:collections 扩展了ListBase。在某些情况下,我遇到能够获取这些类似 List 的对象的排序索引(无需实际对它们进行排序),这很有用。

作为一个父类,我有类似的东西(高度简化):

abstract class A<T> extends ListBase<T> {
  List<T> internalList;
  List<int> orderedIndices();

  ...

}

一个示例后代是这样的:

class B extends A<num> {

  ...

  @override
  List<int> orderedIndices() => new List<int>.generate(
    internalList.length,(i) => i)..sort(
      (i, j) => internalList[i].compareTo(internalList[j]));
}

例如,如果B 的实例将[1, 5, 2, 4, 3] 作为其internalList,则orderedIndices 将按预期返回[0, 2, 4, 3, 1]

我想将实现orderedIndices 的代码放入类A 的定义中,因为只要指定的类型TA 的任何后代,它都是相同的Comparable(即定义了compareTo)。但是,我不知道如何做到这一点,因为在不知道 T 类型的情况下,Dart 无法知道 T 实例是否确实是 Comparable 并且如果我尝试输入代码,就会对 compareTo 咳嗽在A的定义中。

虽然它会起作用,但我反对将代码复制并粘贴到同一类的后代中的想法......有什么方法可以告诉 Dart 在我对 A 的定义中 T 将是Comparable?

【问题讨论】:

  • 知道T 具有可比性对您有何意义?排序是在TcompareTo 中实现的。要获得预期的结果,您需要一个不同的 compareTo 实现 - 在上面的示例中,对于类型 int 的不同实现是不可能的。
  • @GünterZöchbauer:我不确定我是否完全理解你。 int 类型的实现将是相同的。例如,如果C 扩展A&lt;int&gt;(或A&lt;String&gt;A&lt;Any Comparable&gt;),那么要从C 的实例中获取有序索引,我需要复制并粘贴该代码 - 因为它是——从B的定义变成C的定义。我的问题是:这肯定是不好的 OOP 实践,应该在父类中实现功能?
  • 在我们谈论让其他类可以使用该实现之前,我们首先应该能够让它在一个类中工作。我不认为我们还在那里;-)
  • 感谢您的意见,但我认为“我们”中至少有一个已经存在。 :)
  • @GünterZöchbauer :啊-我想我明白误解是什么了。请注意,我不是要对上述代码中的列表进行排序,而是要获取对列表进行排序的 索引序列 ...

标签: oop dart


【解决方案1】:

如果您想将TA 限制为可比较的类型。这是通过限制T 来完成的:

abstract class A<T extends Comparable<T>> extends ListBase<T> {
  ...
  List<int> orderedIndices() => new List<int>.generate(
    internalList.length,(i) => i)..sort(
      (i, j) => internalList[i].compareTo(internalList[j]));
  ...

如果不是所有版本的A 都具有可比性,那么您就不能这样做。然后你可以创建一个A 的辅助子类,即:

abstract class ComparableA<T extends Comparable<T>> extends A<T> {
   List<int> orderedIndices() => new List<int>.generate( ....
   ...
}

然后您可以在可能的情况下使用class B extends ComparableA&lt;num&gt; ... 来共享比较行为,而直接扩展A 的类将需要自己实现该方法。

最后,您可以将 orderedIndices 的规范更改为:

List<int> orderedIndics(int Function(T, T) compare) {
  return List.generate(internalList.length,(i) => i)..sort(
      (i, j) => compare(internalList[i], internalList[j]));
}

然后您可以选择每次调用如何比较internalList 的元素。如果TComparable,则可以使用Comparable.compare 作为实现。

【讨论】:

  • 不错!我不需要任何后代来包装不可比较对象的列表,但这也是很好的信息。
猜你喜欢
  • 2021-05-17
  • 2018-07-30
  • 1970-01-01
  • 2021-10-06
  • 1970-01-01
  • 1970-01-01
  • 2021-10-04
  • 1970-01-01
  • 2021-06-25
相关资源
最近更新 更多