Scala - 如何将通用列表转换为数组并避免 "No ClassTag available for T"
Scala - How to Convert Generic List To Array and avoid "No ClassTag available for T"
我正在研究一段应该是微不足道的代码。我想获取一个列表,并将其转换为等效的数组:
import scala.collection.JavaConverters
object Help extends App {
def f1[T](lst: List[T]) = {
lst.toArray
}
val x = List(1, 2, 3)
println(f1(x))
}
运行 此代码给出:
"No ClassTag available for T"
我怎样才能避免这个问题;我来自 Python 背景,所以希望得到能让我理解这里的机制的回复。
谢谢!
尝试像这样添加隐式 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
向下传递到 toArray
。
would appreciate a response that gives me an understanding of the
mechanics here
关键是要了解 Array
不是 真正的 Scala 集合。这一次,它不是 Iterable
的子类型
implicitly[Array[Int] <:< Iterable[Int]] // error
Array
和真正的 Scala 集合之间的另一个区别是真正的 Scala 集合不需要 ClassTag
。这样做的原因是 Scala 集合经历了一个类型擦除过程,这意味着运行时知道它是一个 List
但不区分 List[Int]
和 List[String]
,例如。然而,这不适用于 Array
。在运行时 Array[Int]
和 Array[String]
之间确实存在差异。因此 ClassTag
是一种发明的机制,用于携带仅在编译时存在的类型信息到运行时,因此 Array
可以具有 Java.
中的行为
你还会遇到其他的区别,比如
Array(42) == Array(42) // false
List(42) == List(42) // true
最佳做法是尽可能避免Array
。
我正在研究一段应该是微不足道的代码。我想获取一个列表,并将其转换为等效的数组:
import scala.collection.JavaConverters
object Help extends App {
def f1[T](lst: List[T]) = {
lst.toArray
}
val x = List(1, 2, 3)
println(f1(x))
}
运行 此代码给出:
"No ClassTag available for T"
我怎样才能避免这个问题;我来自 Python 背景,所以希望得到能让我理解这里的机制的回复。
谢谢!
尝试像这样添加隐式 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
向下传递到 toArray
。
would appreciate a response that gives me an understanding of the mechanics here
关键是要了解 Array
不是 真正的 Scala 集合。这一次,它不是 Iterable
implicitly[Array[Int] <:< Iterable[Int]] // error
Array
和真正的 Scala 集合之间的另一个区别是真正的 Scala 集合不需要 ClassTag
。这样做的原因是 Scala 集合经历了一个类型擦除过程,这意味着运行时知道它是一个 List
但不区分 List[Int]
和 List[String]
,例如。然而,这不适用于 Array
。在运行时 Array[Int]
和 Array[String]
之间确实存在差异。因此 ClassTag
是一种发明的机制,用于携带仅在编译时存在的类型信息到运行时,因此 Array
可以具有 Java.
你还会遇到其他的区别,比如
Array(42) == Array(42) // false
List(42) == List(42) // true
最佳做法是尽可能避免Array
。