2

这是一个无形的简单示例:

  it("from Witness") {

    val ttg = implicitly[TypeTag[Witness.Lt[String]]]
    val ctg = implicitly[ClassTag[Witness.Lt[String]]]
  }

  it("... from macro") {

    val ttg = implicitly[TypeTag[Witness.`1`.T]]
    val ctg = implicitly[ClassTag[Witness.`1`.T]]
  }

  it("... doesn't work") {

    val ttg = implicitly[TypeTag[w1.T]] // failed!
    val ctg = implicitly[ClassTag[w2.T]]
  }

第二个和第三个it块的字节码非常相似(在?调用了 Witness. 宏之后),但是一个成功一个失败:


[Error] /home/peng/git-spike/scalaspike/common/src/test/scala/com/tribbloids/spike/scala_spike/Reflection/InferTypeTag.scala:55: No TypeTag available for com.tribbloids.spike.scala_spike.Reflection.InferTypeTag.w1.T

是什么原因造成的?我该如何规避这个问题?

4

1 回答 1

2

如果你打开scalacOptions += "-Xlog-implicits"你会看到

val w1 = Witness(1)
val ttg = implicitly[TypeTag[w1.T]] // doesn't compile

//materializing requested reflect.runtime.universe.type.TypeTag[App.w1.T] using scala.reflect.api.`package`.materializeTypeTag[App.w1.T](scala.reflect.runtime.`package`.universe)

//scala.reflect.api.`package`.materializeTypeTag[App.w1.T](scala.reflect.runtime.`package`.universe) is not a valid implicit value for reflect.runtime.universe.TypeTag[App.w1.T] because:
//failed to typecheck the materialized tag: 
//cannot create a TypeTag referring to type shapeless.Witness.<refinement>.T local to the reifee: use WeakTypeTag instead

//No TypeTag available for App.w1.T

所以尽量WeakTypeTag按照推荐使用

val w1 = Witness(1)
val ttg2 = implicitly[WeakTypeTag[w1.T]] // compiles

在 Scala 中,为什么无法从类型别名或依赖类型推断 TypeTag?

为什么嵌套实例中没有可用的 TypeTag(当由 scala 代码运行程序解释时)?

类型标签在代码块范围内不起作用?

类型别名搞砸了类型标签?

于 2021-01-09T12:50:58.963 回答