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



下面的代码段按预期返回true:

import scala.reflect.runtime.universe._
typeOf[Seq[Int]] <:< typeOf[Traversable[Int]]

但是这个片段没有:

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

我确信我只是错过了一些明显的东西,但我已经在REPL上工作了几个小时,还没有解决它。如有任何建议,我将不胜感激。

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中描述的擦除,这仍然不能正常工作。

您不需要反射来确定给定的值是否符合给定的静态已知类型。(至少)有两种方法可以做到这一点:

if (someValue.isInstanceOf[SomeType])
  ...
else
  ...

someValue match {
  case st: SomeType => ...
  case _ =>
}

相关内容

  • 没有找到相关文章

最新更新