考虑以下内容:
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
所以等价性被这个变换保留了。我还需要它对参数化类型的工作
来自文档:
需要注意的是,
==
不应该用于比较在存在类型时,==
不能检查类型是否相等,而=:=
可以。
当然,您可以将类型存储在列表中,并使用(例如)以下命令来检查是否包含:
myTypes.exists(_ =:= someType)
例如,您将在2.10编译器源代码中看到这种方法。当然,它不如map或set有效,但通常在集合中不会有很多这样的东西。
如果你一定要有映射或集合的性能,你可以根据你的需求使用erasure
(另一个答案建议)或typeSymbol
。
erasure
scala.reflect.api.Types.TypeApi
的方法:
typeOf[Foo].member(newTermName("bf")).asMethod.paramss.head.head
.typeSignature.erasure == typeOf[Boolean]
// res21: Boolean = true