比较 Scala 中的反射集合类型

Comparing reflected collection types in Scala

我有一个反映的集合类型,我需要比较它是否是某种集合。我该怎么做?

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

当然,这总是错误的。在实践中,我有一个集合列表,用 _ 概括。我需要知道给定的类型(通常在其参数中特定)是否是这些集合之一。例如我需要知道 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 是我需要帮助的地方。如何 "generalize" 特定类型的集合以便地图查找工作?

问题是 aclassSymbol::。它也不包含所包含类型 Int 的类型信息(toString 仅显示泛型)。

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

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

我们可以用它得到a的精确Type,并与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[_]] forSome { type _ } = TypeTag[scala.List[_]]