考虑以下代码:
import scala.reflect.api.Universe
object UnqualifiedTypeTag {
val RuntimeUniverse = scala.reflect.runtime.universe
trait HasUniverse {
val universe: Universe with Singleton
def uType: RuntimeUniverse.TypeTag[universe.type] = implicitly
}
object HasRuntime extends HasUniverse {
override val universe: RuntimeUniverse.type = RuntimeUniverse
}
def main(args: Array[String]): Unit = {
println(HasRuntime.uType)
}
}
理想情况下,程序的这一部分应该产生
TypeTag[HasRuntime.universe.type]
,或者至少编译失败,因为 implicitly
只能看到 universe.type
,这在调用站点是未知的。 (相比之下,WeakTypeTag[universe.type]
应该完全有效)
令人惊讶的是,上面的程序产生了
TypeTag[HasUniverse.this.universe.type]
。这显然违反了许多合同,即:
这样设计的目的是什么,TypeTag提供了什么契约?另外,这就是为什么 ClassTag 应该在 Scala 2.11 之后被取代,而是保持原样直到现在的原因吗?