微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

在scala 2.13中,为什么有时无法推断TypeTags?以及如何从变量符号构造一个?

如何解决在scala 2.13中,为什么有时无法推断TypeTags?以及如何从变量符号构造一个?

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

  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

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

解决方法

如果您打开 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

In Scala,why it is impossible to infer TypeTag from type alias or dependent type?

Why there is no TypeTag available in nested instantiations (when interpreted by scala code runner)?

Typetags not working inside of code block scope?

Type aliases screw up type tags?

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。