Scala 将对象强制转换为类似类型

Scala 将对象强制转换为类似类型,scala,Scala,在斯卡拉。我有两个任意类型的对象。如果可能的话,我想将对象转换为正确的有序特征,然后将它们与(i,j)匹配{ |案例(a:有序的[Any],b:有序的[Any])=>a抛出新的RuntimeException | } 您可以通过排序类型类来实现这一点: def compare[T : Ordering : Manifest](a: AnyRef, b: AnyRef) = { val c = manifest[T].erasure if (c.isAssignableFrom

在斯卡拉。我有两个任意类型的对象。如果可能的话,我想将对象转换为正确的有序特征,然后将它们与<方法进行比较。否则,我想抛出一个异常。应该很简单,但我很困惑…

像这样的东西怎么样

scala> (i, j) match {                                  
     | case (a: Ordered[Any], b: Ordered[Any]) => a < b
     | case _ => throw new RuntimeException            
     | } 
scala>(i,j)匹配{
|案例(a:有序的[Any],b:有序的[Any])=>a抛出新的RuntimeException
| } 

您可以通过
排序
类型类来实现这一点:

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的
可比较的
接口。为此,scala通常有两个特点:

  • Ordred
    -类似于
    Comparable
    ,但现有类(如
    String
    Date
    )没有实现它,因此无法在运行时检查它(至少对于这些类)
  • 排序
    -它是type类,您无法在运行时检索它

另一方面,
Ordered
扩展了
compariable
接口,因此此解决方案也适用于扩展
Ordered
的所有类。为什么不要求对象通过类型系统进行比较呢?出于各种原因,直到运行时我才知道类型。我得到:java.lang.ClassCastException:java.lang.Integer不能转换为scala.math.OrderedRight。我想你的
Any
-值必须是
Ordered
类型才能工作。不幸的是,我直到运行时才知道值的类型。而不是
c.isAssignableFrom(a.getClass)
如何
c.isInstance(a)