4

考虑以下:

scala> import scala.reflect.runtime.universe._
import scala.reflect.runtime.universe._

scala> typeOf[Boolean]
res23: reflect.runtime.universe.Type = Boolean

scala> typeOf[scala.Boolean]
res24: reflect.runtime.universe.Type = Boolean

scala> res23 == res24
res25: Boolean = true

scala> typeOf[java.lang.Boolean]
res26: reflect.runtime.universe.Type = Boolean

scala> res23 == res26
res27: Boolean = false

scala> class Foo { def bf(arg: Boolean) = ??? }
defined class Foo

scala> typeOf[Foo]
res28: reflect.runtime.universe.Type = Foo

scala> res28.member(newTermName("bf")).asMethod
res30: reflect.runtime.universe.MethodSymbol = method bf

scala> res30.paramss.head.head
res31: reflect.runtime.universe.Symbol = value arg

scala> res31.typeSignature
res32: reflect.runtime.universe.Type = scala.Boolean

scala> res32 == res23
res33: Boolean = false

scala> res32 =:= res23
res37: Boolean = true

所以通过 typeOf[Boolean] 函数得到的类型和检查方法得到的类型是等价的,但并不相等。

有没有办法将两种等效类型转换为结果相等的一些规范表示?我希望能够将它们用于地图中的键之类的东西。

编辑:

更清楚地说,我正在寻找的是(不是真正的 repl 会话):

scala>val tp1 = // some type
scala>val tp2 = // equivalent type obtained another way
scala>tp1 == tp2
res1: Boolean = false
scala>tp1 =:= tp2
res2: Boolean = true
scala>val ctp1 = tp1.canonical
scala>val ctp2 = tp2.canonical
scala>ctp1 == ctp2
res3: Boolean = true
scala>ctp1 =:= tp1
res4: Boolean = true
scala>ctp2 =:= tp2
res5: Boolean = true

所以等价性被转换保留。我还需要它来处理参数化类型。

4

2 回答 2

4

文档中

需要注意的是,==不应使用它来比较类型的相等性——<code>== 不能在存在类型别名的情况下检查类型相等性,而=:=可以。

您当然可以将类型存储在列表中并使用(例如)以下内容来检查是否包含:

myTypes.exists(_ =:= someType)

例如,您将在 2.10 编译器源代码中看到这种方法。当然,它不如地图或集合那么有效,但是您通常不会在集合中拥有很多此类东西。

如果您绝对必须具有地图或集合的性能,则可以根据您的要求使用erasure(如另一个答案所示)或。typeSymbol

于 2012-12-27T21:12:32.003 回答
2

erasure方法scala.reflect.api.Types.TypeApi

typeOf[Foo].member(newTermName("bf")).asMethod.paramss.head.head
  .typeSignature.erasure == typeOf[Boolean]
// res21: Boolean = true
于 2012-12-27T20:59:55.583 回答