scala - 有没有办法将 Scala 反射中的两个等效类型转换为两个相等的类型?

标签 scala reflection scala-2.10

考虑以下:

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] 函数得到的类型等价于通过检查一个方法得到的类型,但不相等。

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

编辑:

更清楚地说,我正在寻找的是(不是真正的 repl session ):
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

因此,转换保留了等价性。我还需要它来处理参数化类型。

最佳答案

来自 the documentation :

It's important to note that == should not be used to compare types for equality—== can't check for type equality in the presence of type aliases, while =:= can.



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

例如,您将在 2.10 编译器源代码中看到这种方法。当然,它不如 map 或集合有效,但您通常在一个集合中没有很多这样的东西。

如果你绝对有 map 或集的表现,你或许可以使用erasure (如另一个答案所示)或 typeSymbol ,取决于您的要求。

关于scala - 有没有办法将 Scala 反射中的两个等效类型转换为两个相等的类型?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14060522/

相关文章:

scala - 将项目添加到新的字符串列表

mysql - 如何让Slick建表语句使用InnoDB

json - 将嵌套列表转换为 json 会产生多余的数组

c# - 从 C# 中的基类获取派生类型?

避免 NoSuchMethodError 需要反射(reflection)吗?

c# - ParameterInfo 是扩展方法参数?

scala - 在 Scala 中使用反射的奇怪行为

scala - Spark exitCode : 12 mean? 是什么意思

java - 参数类型不是协变的吗?

scala - 如何在 Scala 宏中构建动态序列?