如何使用Scala 2.10反射API检查运行时实例是否符合某种类型?

Mat*_*rts 2 reflection scala

以下代码段按预期返回true:

import scala.reflect.runtime.universe._
typeOf[Seq[Int]] <:< typeOf[Traversable[Int]]
Run Code Online (Sandbox Code Playgroud)

但是,这段代码不是:

val s = Seq[Int](1,2,3)
val m = runtimeMirror(this.getClass.getClassLoader)
val t = m.reflect(s).symbol.typeSignature
t <:< typeOf[Seq[Int]]
Run Code Online (Sandbox Code Playgroud)

我确信我只是遗漏了一些显而易见的东西,但我已经在REPL上工作了几个小时而且还没有解决.任何建议将不胜感激.提前致谢.

Eug*_*ako 6

1)typeOf[...]从Java擦除中保留精确的Scala类型,然而,obj.getClass(因此m.reflect(obj),getClass在封面下使用)则没有.因此,最好的运行时反射可以从反射中得到,s而无需额外的编译时工作Seq[_](这将使子类型测试失败).如果你需要为运行时记住某些东西的精确Scala类型,请使用类型标记(就像typeOf那样)或宏(就像类型标记一样).

2).symbol.typeSignature不会起作用,因为那是ClassInfoType(即一种类型,它封装了父类列表和类类型的成员).类信息类型非常适合检查成员(可能也用于基类,也可能用于更多的东西,但我不确定是否在我的头脑中),但对其他一切都不是那么好.你想要找到类似的东西.symbol.asType.toType,它会返回一个TypeRef(即在我们的例子中scala.collection.immutable.::- 注意这里缺少任何类型的参数!).不幸的是,由于#1中描述的擦除,它仍然无法开箱即用.