#scala #generics #operator-overloading
#scala #дженерики #оператор-перегрузка
Вопрос:
Ниже приведена функция быстрой сортировки, написанная на Scala для сортировки списка смешанных типов (int, double, float и т. Д.). В строке 3 появилась ошибка с надписью «Несоответствие типов, ожидаемое: T => Логическое значение, фактическое: T => Любой не может разрешить символ <«. Как мне это исправить?
IDE Intellij, работающая в Windows 10, выдала это сообщение об ошибке.
def qsort[T](list: List[T]): List[T] = list match {
case Nil => Nil
case pivot :: tail =>
val(smaller, rest) = tail.partition(_ < pivot)
qsort(smaller) ::: pivot :: qsort(rest)
}
Комментарии:
1. Как бы вы сравнили произвольные типы?
T
должен бытьComparable
тип, если вы хотите его сравнить.2. В C сопоставимые типы не нужно указывать, если у них есть operator < <= и т.д. Но я не знаком с механизмом в Scala.
3. C проверяет наличие
<
etc. когда вы вызываете универсальную функцию, но Scala выполняет эту проверку при компиляции функции. Scala должен быть уверен, что он будет работать для всех возможныхT
, поэтому вам нужно как-то ограничить допустимые типы. Вы можете ограничить сам тип или добавитьimplicit
параметр.
Ответ №1:
Ответ Дмитрия будет работать для любого типа, в который можно неявно преобразовать Ordered[T]
. Это немного странно, и в идиоматическом Scala люди часто предпочитают Ordering
вместо этого использовать неявный. Таким образом, порядок полностью отделен от реализации T
.
def qsort[T : Ordering](list: List[T]): List[T]
Подпись использует привязку к контексту и [T: Ordering]
является синтаксическим сахаром для более подробного
def qsort[T](list: List[T])(implicit ev: Ordering[T]): List[T]
Если вы пришли с Java, Ordering
это Ordered
то, что Comparator
нужно Comparable
. Обратите внимание, что Ordering[T]
по духу это очень похоже на T => Ordered[T]
, но я думаю, что проще обернуть голову, когда вы новичок. Это также дает вам хороший набор методов для создания и управления Ordering
s.
Наконец, обратите внимание, что использование List
для метода сортировки, такого как быстрая сортировка, приведет к действительно низкой производительности, потому что добавление к a List
есть O(n)
. Если производительность вызывает беспокойство, используйте Array
с встроенной реализацией быстрой сортировки.
Комментарии:
1.С вашим исправлением используемый синтаксис TS
_ < pivot
работает только послеval ev = Ordering[T]
import ev._
Ответ №2:
Добавить неявный параметр
def qsort[T](list: List[T])(implicit ev: T => Ordered[T]) = ...