在 Scala 2.13 中,为什么可以为抽象类型调用不合格的 TypeTag?

问题描述 投票:0回答:0

考虑以下代码:

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 不能从抽象类型初始化,不像 WeakTypeTag
  • TypeTag 总是可以擦除到一个 Class

这样设计的目的是什么,TypeTag提供了什么契约?另外,这就是为什么 ClassTag 应该在 Scala 2.11 之后被取代,而是保持原样直到现在的原因吗?

scala implicit type-erasure scala-2.13
© www.soinside.com 2019 - 2024. All rights reserved.