以下代码中的toArray调用无法编译
trait A[T] {
def create:T
def foo(a:Array[Int]) = {
for(b <- a) yield create
}.toArray
}
它会引发以下错误:
not enough arguments for method toArray: (implicit evidence$1: scala.reflect.ClassTag[T])Array[T]. Unspecified value parameter evidence$1.
No ClassTag available for T
我该如何解决?
答案 0 :(得分:2)
正如谢尔盖所说,Java数组需要知道T的类型,但是T
被类型擦除所消除。
在scala中,您可以使用ClassTag
在运行时“保留”类型信息。
这是关于数组的更多in-depth discussion。
根据修正,您需要为ClassTag
提供T
的证据。这是一个可能的解决方案:
import scala.reflect.ClassTag
trait A[T] {
def create: T
def foo(a: Array[Int])(implicit ev: ClassTag[T]) = {
for(b <- a) yield create
}.toArray
}
隐式ev
参数由编译器自动填充。
答案 1 :(得分:1)
最简单的方法是删除toArray
电话。因为你遍历数组所以你的结果也是数组。
答案 2 :(得分:1)
问题在于,您无法在不知道Array[T]
的情况下创建T
。 ClassTag
是Scala表示此信息的方式。简单的解决方法是将trait A[T]
更改为abstract class A[T: ClassTag]
(需要类,因为traits可以包含任何构造函数参数,包括隐式参数)。然后,如果您使用特定的类型创建它,例如class B extends A[Int]
,编译器会插入正确的ClassTag
本身,并且需要通用ClassTag
通过:class C[T: ClassTag] extends A[T]
。