Вы можете реализовать это с Ordering
классом типа:
def compare[T : Ordering : Manifest](a: AnyRef, b: AnyRef) = {
val c = manifest[T].erasure
if (c.isAssignableFrom(a.getClass) && c.isAssignableFrom(b.getClass))
implicitly[Ordering[T]].compare(a.asInstanceOf[T], b.asInstanceOf[T])
else
throw new IllegalArgumentException("Wrong argument type")
}
А затем используйте это так:
compare[Date](new Date, new Date)
compare[String]("A", "B")
Но этот код выдаст IllegalArgumentException
:
compare[Date]("A", "B")
Обновление
Если вы действительно не знаете типы объектов, которые вы пытаетесь сравнить, тогда вы можете использовать это решение:
def compare(a: AnyRef, b: AnyRef) = {
val c = classOf[Comparable[_]]
if (c.isAssignableFrom(a.getClass) && c.isAssignableFrom(a.getClass) && a.getClass == b.getClass) {
a.asInstanceOf[Comparable[AnyRef]].compareTo(b.asInstanceOf[Comparable[AnyRef]])
} else {
throw new IllegalArgumentException("Incopatible argument types: " + a.getClass.getName + " and " + b.getClass.getName)
}
}
Это относится к интерфейсу Comparable
Java. Обычно в scala есть 2 черты для этой цели:
Ordred
- аналогично Comparable
, но существующие классы (например, String
или Date
) не реализуют его, поэтому вы не можете проверить его во время выполнения (по крайней мере, для этих классов)
Ordering
- это класс типов, и вы не можете получить его во время выполнения.
С другой стороны, Ordered
расширяет интерфейс Comparable
, поэтому это решение также должно работать для всех классов, которые расширяют Ordered
.