关于Scala泛型:找不到元素类型T的类清单

xim*_*myu 8 generics scala

对于以下功能:

def reverse[T](a: Array[T]): Array[T] = {
    val b = new Array[T](a.length)
    for (i <- 0 until a.length)
        b(i) = a(a.length -i - 1)
    b
}
Run Code Online (Sandbox Code Playgroud)

我从第2行得到"错误:无法找到元素类型T的类清单".

反正有没有解决这个问题?

Aar*_*rup 10

只需在方法声明中添加一个上下文绑定的ClassManifest:

def reverse[T : ClassManifest](a: Array[T]): Array[T] = ...
Run Code Online (Sandbox Code Playgroud)

为了构造数组,必须在编译时知道数组的具体类型.此类型由编译器通过隐式ClassManifest参数提供.也就是说,Array构造函数的签名实际上是

Array[T](size: Int)(implicit m: ClassManifest[T]): Array[T]
Run Code Online (Sandbox Code Playgroud)

为了提供此参数,在调用Array构造函数时,范围内必须有ClassManifest.因此,您的反向方法还必须采用隐式ClassManifest参数:

def reverse[T](a: Array[T])(implicit m: ClassManifest[T]): Array[T] = ...
// or equivalently
def reverse[T : ClassManifest](a: Array[T]): Array[T] = ...
Run Code Online (Sandbox Code Playgroud)

后者,更简单的表示法称为上下文绑定.

  • `ClassManifest`只要求编译器知道类型的类.`Manifest`要求编译器也知道它的所有类型参数.例如.对于`List [String]`,前者只需要知道`List`,而后者需要`List [String]`.要创建Java数组,只需要前者. (10认同)
  • 有关ClassManifest与Manifest问题的详细解答,请访问http://stackoverflow.com/questions/3213510/what-is-a-manifest-in-scala-and-when-do-you-need-it (4认同)