【发布时间】:2014-06-18 11:53:19
【问题描述】:
让我们从一个示例代码开始:
import scala.reflect.runtime.universe._
class A[T] {
}
def foo[T: TypeTag](a: A[T]) {
println(typeTag[T])
}
val a = new A[Int]
val b: A[_] = a
foo(a)
foo(b)
输出是:
TypeTag[Int]
TypeTag[_$1]
好吧,我不知道TypeTag[_$1] 是什么,但它确实看起来很漂亮。 :) 尽管如此,我认为 foo 对世界的期望在这里被违反了,如果 foo 被一个 A[Int] 的实例调用,那么它保证有 Int 的类型标签,而不是其他一些晦涩的类型标签。另外,与 weektypetags 相比,typetags 不应该是“具体的”吗?
现在我当然看到编译器在第二次 foo 调用中无法分辨出 A 的类型参数。所以我的期望不是我神奇地将 typeTag[Int] 作为第二次调用的输出,而是我希望编译时错误。
我的误解在哪里?
一些徒劳的猜测
有人可能会争辩说,正在发生的事情是使用参数类型 A[_] 调用 foo,或者更明确地说,是存在类型 A[S] forSome { type S }。然后 typeTag 以某种方式捕获“_”。但这并没有真正的意义,因为 foo 期望 A[T] 用于某些具体的T,而上述存在类型不是A[T] 用于任何具体的T。
或者可能是带有参数A[Any] 的调用?但是为什么不是TypeTag[Any],更严重的是,A 不是协变的,所以这也是完全错误的。
顺便说一句,我使用的是 scala 2.10。
【问题讨论】:
标签: scala reflection