Scala通用方法-T没有可用的ClassTag


74

我对Scala比较陌生,正在尝试定义通用对象方法。但是,当我在方法中引用参数化类型时,将得到“ T没有可用的ClassTag”。这是一个说明问题的人为示例。

scala> def foo[T](count: Int, value: T): Array[T] = Array.fill[T](count)(value)
<console>:7: error: No ClassTag available for T
       def foo[T](count: Int, value: T): Array[T] = Array.fill[T](count)(value)
                                                                        ^

在此先感谢您的帮助,以帮助您理解此处的错误以及如何使此示例示例起作用。

Answers:


90

为了在通用上下文中实例化一个数组(实例化类型参数为Twhere的数组T),Scala需要在运行时获取有关信息T,其形式为type的隐式值ClassTag[T]。具体而言,您需要方法的调用者(隐式地)传递此ClassTag值,这可以使用上下文绑定方便地完成:

def foo[T:ClassTag](count: Int, value: T): Array[T] = Array.fill[T](count)(value)

有关此情况的(详尽的)描述,请参阅以下文档:

https://docs.scala-lang.org/sips/scala-2-8-arrays.html

(简而言之,ClassTag是ClassManifests的重新实现,因此基本原理仍然存在)


13
迷人。使用'import scala.reflect.ClassTag'可以工作。谢谢。
Chuck 2013年

3
人们也可能会觉得这很有启发性-docs.scala-lang.org/overviews/reflection / ...-因为ClassManifests即将消失。
Chuck

如果我们在函数体中对T类型的两个值进行任何比较,则implicit除了ClassTag注释外,还需要一个orderer参数。
AlvaPan

我发现这个面向Java的问题也有助于理解为什么我们不需要诸如列表之类的ClassTag,但是Martin的SIP也暗示了这一点:stackoverflow.com/questions/1817524/generic-arrays-in-java
bbarker
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.