尝试像这样添加隐式ClassTag
参数
import scala.reflect.ClassTag
def f1[T](lst: List[T])(implicit ev: ClassTag[T]) = {
lst.toArray
}
如果我们看一下签名,原因就很清楚了toArray
def toArray[B >: A: ClassTag]: Array[B]
这相当于
def toArray[B >: A](implicit ev: ClassTag[B]): Array[B]
所以你必须将隐式参数从f1
down 线程化到toArray
.
将不胜感激让我了解这里的机制的回应
关键是要理解Array
不是真正的Scala 集合。这一次,它不是Iterable
implicitly[Array[Int] <:< Iterable[Int]] // error
与真正的 Scala 集合之间的另一个区别Array
是不需要ClassTag
真正的 Scala 集合。原因是 Scala 集合经历了类型擦除过程,这意味着运行时知道它是 aList
但不区分List[Int]
and List[String]
,例如。然而,这并不成立Array
。Array[Int]
在运行时和之间确实存在差异Array[String]
。因此ClassTag
,发明了一种用于携带类型信息的机制,该信息仅存在于编译时,一直到运行时,因此Array
可以具有 Java 中的行为。
您将遇到其他差异,例如
Array(42) == Array(42) // false
List(42) == List(42) // true
最佳做法是尽可能避免Array
。