2

以下代码段按预期返回 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 上待了几个小时,但还没有解决。任何建议将不胜感激。提前致谢。

4

2 回答 2

6

1)typeOf[...]保留了 Java 擦除的确切 Scala 类型,但是obj.getClass(因此m.reflect(obj),它getClass在幕后使用)没有。因此,最好的运行时反射可以通过在s没有额外编译时努力的情况下进行反射Seq[_](这将导致子类型测试失败)。如果您需要在运行时记住某些东西的确切 Scala 类型,请使用类型标签(就像这样typeOf做)或宏(就像类型标签一样)。

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

于 2013-04-14T20:44:03.110 回答
1

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

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

或者

someValue match {
  case st: SomeType => ...
  case _ =>
}
于 2013-04-14T20:28:26.643 回答