我有一个带有泛型类型参数的类,我想获得对泛型类型的构造函数的引用。
如果我导入整个scala.reflect.runtime.universe._而不是导入别名(例如“ru”),这只能在没有删除警告的情况下工作。
我不清楚原因是什么。我怀疑隐含必须从宇宙进入范围,但是没有通过IntelliJ的隐式工具找到任何相关的东西。
任何人都可以告诉我为什么会这样,如果是隐含的,哪一个?
此编译没有警告:
import scala.reflect.runtime.universe._
class CaseClassesExample[T :TypeTag] {
def doWork: Unit = {
val tpe = weakTypeTag[T].tpe
val ctor = tpe.decls.collectFirst {
case m: MethodSymbol if m.isPrimaryConstructor => m
}
}
}
这会编译MethodSymbol的擦除警告:
import scala.reflect.runtime.{universe => ru}
class CaseClassesExample[T : ru.TypeTag] {
def doWork: Unit = {
val tpe = ru.weakTypeTag[T].tpe
val ctor = tpe.decls.collectFirst {
case m: ru.MethodSymbol if m.isPrimaryConstructor => m
}
}
}
警告:
[warn] abstract type pattern reflect.runtime.universe.MethodSymbol is unchecked since it is eliminated by erasure
[warn] case m: ru.MethodSymbol => m.isConstructor && m.isPrimaryConstructor
[warn] ^
拆分导入:
为了缩小范围,我按如下方式拆分导入 - 有趣的是,IntelliJ声明第二次导入未使用,但删除它会带回警告:
import scala.reflect.runtime.{universe => ru}
class CaseClassesExample[T : ru.TypeTag] {
def doWork: Unit = {
val tpe = ru.weakTypeTag[T].tpe
import scala.reflect.runtime.universe._
//IntelliJ highlights above import as unused - but removing it brings warning back
val ctor = tpe.decls.collectFirst {
case m: ru.MethodSymbol if m.isPrimaryConstructor => m
}
}
}
答案 0 :(得分:1)
原因很简单。 Universe
有一个名为MethodSymbolTag
的隐式方法(从Symbols
特征中混入)定义如下:
implicit val MethodSymbolTag: ClassTag[Universe.MethodSymbol]
范围中存在ClassTag[Universe.MethodSymbol]
允许编译器进行擦除。
您可以通过在第二个代码段中添加此导入来验证这一点:
import ru.MethodSymbolTag