有没有一种方法可以将Scala反射中的两个等价类型转换为两个等价类型?



考虑以下内容:

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

相关内容

  • 没有找到相关文章

最新更新