在斯卡拉。我有两个Any类型的对象。如果可能的话,我想将对象强制转换为正确的Ordered特征,然后将它们与<方法。否则,我想抛出异常。应该很简单,但我很难过......
答案 0 :(得分:6)
您可以使用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)
}
}
它归结为Java的Comparable
接口。通常,scala有两个特征用于此目的:
Ordred
- 与Comparable
类似,但现有的类(如String
或Date
)没有实现它,因此您无法在运行时检查它(在至少对于这些课程而言)Ordering
- 它是类型类,您无法在运行时检索它。另一方面,Ordered
扩展了Comparable
接口,因此此解决方案也适用于所有扩展Ordered
的类。
答案 1 :(得分:0)
这样的事情怎么样?
scala> (i, j) match {
| case (a: Ordered[Any], b: Ordered[Any]) => a < b
| case _ => throw new RuntimeException
| }