A => Class [A]使用ClassTag?

时间:2016-09-11 02:26:47

标签: scala reflection

查看ClassTag#runtimeClass,它的返回类型为Class[_],即Class,据我了解,它是一个通配符参数。

我尝试实施一种方法:A => ClassTag[A]

import scala.reflect._

scala> def f[A](x: A)(implicit ev: ClassTag[A]) = ev.runtimeClass
f: [A](x: A)(implicit ev: scala.reflect.ClassTag[A])Class[_]

但是,正如文档所示,def定义的输出是Class[_]

是否可以更改f以使其返回类型为Class[A]?如果没有,那为什么不可能?

1 个答案:

答案 0 :(得分:5)

除非您更改f的签名,否则您唯一的选择是将Class[_]转换为Class[A]

整个Scala标准库中只有一种方法返回Class[A],即classOf。无法重写f[A]以使用classOf[A],因为它是一种特殊的编译器方法,并且与可能不是类的泛型类型参数不兼容。你只会得到一个错误:

scala> def f[A: ClassTag](x: A) = classOf[A]
<console>:10: error: class type required but A found
       def f[A: ClassTag](x: A) = classOf[A]
                                          ^

您可以使用x.getClass获得最佳效果,但这将返回Class[_ <: A](不需要ClassTag)。

scala> def f[A](x: A): Class[_ <: A] = x.getClass
f: [A](x: A)Class[_ <: A]

scala> f(1)
res8: Class[_ <: Int] = class java.lang.Integer

scala> f(List(1, 2, 3))
res9: Class[_ <: List[Int]] = class scala.collection.immutable.$colon$colon

你可能会问,为什么_ <: A

这个问题的答案也是你f的定义没有意义的原因。如果AInt,则能够返回Class[A]是有意义的,因为Int是一个类。但是如果AList[Int]怎么办? List[Int]不是一个类,它是一个类型。该课程为List,但A != List,因此我们无法始终如一地返回Class[A]。但是,我们可以A的类型参数上有Class的上限。