Scala 一个toArray函数,它在基元类型上中断,但作为PartialFunction编写时工作良好?
在使用反射基代码时,我遇到了一个难题,我想将序列转换为数组。问题在于,唯一可用的类型信息是Scala 一个toArray函数,它在基元类型上中断,但作为PartialFunction编写时工作良好?,scala,scala-reflect,partialfunction,Scala,Scala Reflect,Partialfunction,在使用反射基代码时,我遇到了一个难题,我想将序列转换为数组。问题在于,唯一可用的类型信息是runtime.universe.type,序列本身的类型是Seq[Any] 我试图调用Seq上的toArray方法,它需要一个我没有的ClassTag。天真地,我只是在运行时类型之外创建了一个ClassTag[Any],如下所示: import scala.reflect.runtime.{universe => ru} import scala.reflect.ClassTag val mirr
runtime.universe.type
,序列本身的类型是Seq[Any]
我试图调用Seq上的toArray
方法,它需要一个我没有的ClassTag
。天真地,我只是在运行时类型之外创建了一个ClassTag[Any]
,如下所示:
import scala.reflect.runtime.{universe => ru}
import scala.reflect.ClassTag
val mirror = ru.runtimeMirror(getClass.getClassLoader)
def anyClassTag(tpe: ru.Type) = ClassTag[Any](mirror.runtimeClass(tpe))
def toArray1(items: Seq[Any]) = (tpe: ru.Type) => {
items.toArray(anyClassTag(tpe))
}
当使用基元类型调用时,这会以CastClassException
失败,这是出人意料的
toArray1(Seq(1,2,3))(ru.typeOf[Int]) foreach print // java.lang.ClassCastException: [I cannot be cast to [Ljava.lang.Object;
但是,如果函数被重写为部分函数
,那么它会以某种方式工作
def toArray2(items: Seq[Any]) : PartialFunction[ru.Type, Array[Any]] = { case tpe =>
items.toArray(anyClassTag(tpe))
}
toArray2(Seq(1,2,3))(ru.typeOf[Int]) foreach print // Successfully prints 123 !
但这似乎非常脆弱。稍微修改一下就很容易再把它弄坏。例如:
def toArray3(items: Seq[Any]) : PartialFunction[ru.Type, Array[Any]] = { case tpe =>
val results = items.toArray(anyClassTag(tpe))
results
}
toArray3(Seq(1,2,3))(ru.typeOf[Int]) foreach print // ClassCastException again!
所以问题是,这里发生了什么魔法?为什么
toArray2
是唯一有效的,而且应该有效?Scala中的运行时反射速度慢,并且有许多严重的错误,包括回归。请使用已打开或最近关闭的bug列表检查您的Scala版本: