比较Scala中的反射集合类型

时间:2015-03-17 16:16:05

标签: scala reflection

我有一个需要比较的反射集合类型,看它是否是某种集合。我怎么能这样做?

val a = List(1,2,3)
val b = currentMirror.classSymbol(a.getClass).typeSignature
println("Q? "+ (b =:= typeOf[List[_]]))

当然,这总是错误的。在实践中,我有一个集合列表,用_一般化。我需要知道给定的Type(通常在其参数中是特定的)是否是这些集合之一。例如,我需要知道List [Int]是否是List [_]。

实际情况是这样的:泛型类型的地图 - >功能我需要的东西:

val collectionHandlers = Map(
    typeOf[scala.collection.immutable.List[_]] -> fnList,
    typeOf[scala.collection.immutable.Map[_,_]] -> fnMap,
    //...
)
val aListType = // something here that is a TypeSignature of List[Int] as above
collectionHandlers( _magicClean(aListType) )()

_magicClean是我需要帮助的地方。如何“概括”特定类型的集合,以便地图查找起作用?

1 个答案:

答案 0 :(得分:0)

问题在于a classSymbol::。它也不包含所包含类型Int的类型信息(toString仅显示泛型)。

说,如果我们有这样的方法:

def typeTagOf[A](a: A)(implicit tt: TypeTag[A]) = tt

我们可以使用它来获取Type的确切a,并将其与typeOf[List[_]]进行比较。

scala> typeTagOf(a).tpe <:< typeOf[List[_]]
res165: Boolean = true

scala> typeTagOf(1).tpe <:< typeOf[List[_]]
res166: Boolean = false

List[Int]List[_],这就是我使用<:<代替=:=的原因。也就是说,List[Int]List[_]的子类型,但它们的类型并不完全相同。它并不是很清楚你需要什么。如果你只匹配集合类型(没有内部类型),你可能会使用List[_]等等。但是有一些警告。例如,如果你有这个:

val list: List[_] = List(1, 2, 3)

您无法恢复类型信息并证明它只是Int的列表,因为_是一种存在类型。

scala> typeTagOf(list)
res170: reflect.runtime.universe.TypeTag[List[_$1]] forSome { type _$1 } = TypeTag[scala.List[_$1]]