为什么ClassManifest需要Array而不是List?

Jus*_*s12 12 scala scala-2.8 scala-collections

定义以下代码:

import scala.collection.JavaConversions._  
val iter:java.util.Iterator[Any] = Array[Any](1, 2, 3).iterator
def func(a:Any):String = a.toString

def test[T:ClassManifest](iter:java.util.Iterator[Any], func:Any=>T):Array[T] =  
  iter.map(i=>func(i)).toArray

def testFunc = test(iter, func)
Run Code Online (Sandbox Code Playgroud)

在这里,我需要使用ClassManifest它来正确编译,否则我得到错误:

scala> def test[T](iter:java.util.Iterator[Any], func:Any=>T):Array[T] = 
     |   iter.map(i=>func(i)).toArray         

<console>:11: error: could not find implicit value for evidence parameter of 
type ClassManifest[T]
     iter.map(i=>func(i)).toArray
                          ^
Run Code Online (Sandbox Code Playgroud)

另一方面,下面使用的替代代码List不需要这个并编译好.

import scala.collection.JavaConversions._  
val iter:java.util.Iterator[Any] = Array[Any](1, 2, 3).iterator
def func(a:Any):String = a.toString 

def test1[T](iter:java.util.Iterator[Any], func:Any=>T):List[T] = 
  iter.map(i=>func(i)).toList   


def testFunc1 = test1(iter, func).toArray
Run Code Online (Sandbox Code Playgroud)

请注意,最终输出testFunctestFunc1相同.

为什么List版本不需要ClassManifest

Dan*_*ral 11

Java中的数组不是类型擦除的,特别Array[Int]是a不同于Array[Object]JVM级别的数组.

对于任何其他类别,类型参数被擦除至Object,所以List[Int]List[Object]具有JVM级别相同的表示.


ten*_*shi 10

Method toArray使用类型的元素创建新数组T.并根据文件:

因此,根据T的实际类型参数,这可能是Array [Int],或Array [Boolean],或Java中某些其他基本类型的数组,或某些引用类型的数组.但是这些类型具有所有不同的运行时表示,那么Scala运行时如何选择正确的运行时表示?实际上,它不能基于给出的信息来做到这一点,因为对应于类型参数T的实际类型在运行时被擦除.