Определение типа для `Comparable` в Dart - PullRequest
0 голосов
/ 29 июня 2018

Этот вопрос может возникнуть из-за неадекватного понимания ООП в Dart, но в любом случае:

Я работал над проектом, для которого один из моих базовых классов расширяет ListBase с dart:collections. В некоторых случаях бывает полезно получить отсортированные индексы этих объектов, подобных списку (без их сортировки).

Как родительский класс у меня есть что-то вроде (сильно упрощенное):

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, однако, поскольку он будет идентичен любому из потомков A, пока указанный тип T равен Comparable (т.е. определено compareTo). Однако я не знаю, как это сделать, потому что, не зная типа T, Дарт не может узнать, действительно ли экземпляры T действительно Comparable, и кашляет на compareTo, если я пытаюсь поставить код в определении A.

Хотя это сработало бы, я отказываюсь от идеи копировать и вставлять код в потомков того же класса ... Есть ли какой-то способ, которым я могу сказать Дарту в своем определении A, что T будет Comparable?

1 Ответ

0 голосов
/ 29 июня 2018

Если вы хотите ограничить T из A типами, которые сопоставимы. Это делается путем наложения 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<num> ..., чтобы поделиться поведением сравнения, когда это возможно, и классы, непосредственно расширяющие 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. Если T равно Comparable, вы можете использовать Comparable.compare в качестве реализации.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...