将对象转换为可比类型

时间:2011-05-28 19:22:52

标签: scala

在斯卡拉。我有两个Any类型的对象。如果可能的话,我想将对象强制转换为正确的Ordered特征,然后将它们与<方法。否则,我想抛出异常。应该很简单,但我很难过......

2 个答案:

答案 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类似,但现有的类(如StringDate)没有实现它,因此您无法在运行时检查它(在至少对于这些课程而言)
  • Ordering - 它是类型类,您无法在运行时检索它。

另一方面,Ordered扩展了Comparable接口,因此此解决方案也适用于所有扩展Ordered的类。

答案 1 :(得分:0)

这样的事情怎么样?

scala> (i, j) match {                                  
     | case (a: Ordered[Any], b: Ordered[Any]) => a < b
     | case _ => throw new RuntimeException            
     | }