Scala 泛型方法 - 没有可用于 T 的 ClassTag

Posted

技术标签:

【中文标题】Scala 泛型方法 - 没有可用于 T 的 ClassTag【英文标题】:Scala generic method - No ClassTag available for T 【发布时间】:2013-06-04 15:00:54 【问题描述】:

我对 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)
                                                                        ^

在此先感谢您帮助了解这里出了什么问题以及如何使这个人为的示例工作。

【问题讨论】:

【参考方案1】:

要在通用上下文中实例化一个数组(实例化一个T 的数组,其中T 是一个类型参数),Scala 需要在运行时以隐式类型值的形式获得关于T 的信息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

(简而言之,ClassTags 是 ClassManifests 的重新设计实现,所以基本原理仍然存在)

【讨论】:

令人着迷。使用 'import scala.reflect.ClassTag' 这行得通。谢谢。 人们可能会发现这也很有启发性 - docs.scala-lang.org/overviews/reflection/… - 因为 ClassManifests 即将消失。 如果我们在函数体中对两个 T 类型的值进行比较,除了ClassTag 注释之外,我们还需要一个implicit orderer 参数。 我发现这个面向 Java 的问题也有助于理解为什么我们不需要 ClassTags,例如列表,但 Martin 的 SIP 也暗示了这一点:***.com/questions/1817524/generic-arrays-in-java

以上是关于Scala 泛型方法 - 没有可用于 T 的 ClassTag的主要内容,如果未能解决你的问题,请参考以下文章

scala manifest和classmanifest的区别

Scala泛型[T]的使用

Scala中泛型类型的模式匹配

Scala - 从泛型类型获取类对象

scala高级类型

scala高级类型