请考虑以下事项:
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
因此,转换会保留等效性。我还需要它来处理参数化类型。
答案 0 :(得分:4)
重要的是要注意
==
不应该用于比较类型 等式 -==
在类型存在时无法检查类型是否相等 别名,而=:=
可以。
您当然可以将类型存储在列表中并使用(例如)以下内容来检查包含:
myTypes.exists(_ =:= someType)
例如,您将在2.10编译器源中看到此方法。当然,它不如地图或集合那么高效,但是你通常在集合中没有很多这样的东西。
如果您必须具有地图或集合的效果,则可以使用erasure
(如另一个答案所示)或typeSymbol
,具体取决于您的要求。
答案 1 :(得分:2)
erasure
的 scala.reflect.api.Types.TypeApi
方法:
typeOf[Foo].member(newTermName("bf")).asMethod.paramss.head.head
.typeSignature.erasure == typeOf[Boolean]
// res21: Boolean = true