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)