方法toArray没有足够的参数

时间:2016-06-09 07:57:10

标签: scala generics

以下代码中的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 

我该如何解决?

3 个答案:

答案 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]的情况下创建TClassTag是Scala表示此信息的方式。简单的解决方法是将trait A[T]更改为abstract class A[T: ClassTag](需要类,因为traits可以包含任何构造函数参数,包括隐式参数)。然后,如果您使用特定的类型创建它,例如class B extends A[Int],编译器会插入正确的ClassTag本身,并且需要通用ClassTag通过:class C[T: ClassTag] extends A[T]