如何在Scala中知道Map值Map(“ key->” value“)的类型?

时间:2019-01-20 20:59:30

标签: scala reflection type-variables

我的Map(“ id”)值有问题,它可能有两种类型:String或Map [String,String]。

Case 1: val a = Map("id" -> "123")
Case 2: val a = Map("id"-> Map("ide"->"abcd"))

我想用这样的Match案例进行检查:

def d = a.get("id") match {

  case _:String => "String"
  case _:Map[String,Any] => "Map"


}

有人知道我应该如何处理此案吗?

2 个答案:

答案 0 :(得分:2)

您的代码几乎正确。地图上的方法get返回一个Option。您需要做的就是将值包装在match中。因此,您可以执行以下操作:

val a1 = Map("id" -> "123")
val a2 = Map("id" -> Map("ide" -> "abcd"))
val a3 = Map("id" -> 42)

def d(map: Map[String, Any]) = map.get("id") match {
  case Some(_: String) => "String"
  case Some(_: Map[String,Any]) => "Map"
  case _ => "Other"

}

d(a1) // "String"
d(a2) // "Map"
d(a3) // "Other"

UPD:正如@Luis指出的那样,由于类型擦除,第二种情况将匹配任何Map。如果您要匹配特定的Map

,请查看他的答案

答案 1 :(得分:2)

从德米特里的答案中得到明显修饰。此代码段使用TypeTagOvercome type erasure

import scala.reflect.runtime.universe.{TypeTag, typeOf}

def d[T](map: Map[String, T])(implicit T: TypeTag[T]) = map.get("id") match {
  case Some(_) if T == typeOf[String] => "String"
  case Some(_) if T == typeOf[Map[String, String]] => "Map[String, String]"
  case Some(_) => "Other"
  case None => "Not found"
}

d(Map("id" -> "Hello")) // String.
d(Map("id" -> Map("Hello" -> "World"))) // Map[String, String].
d(Map("id" -> 10)) // Other.
d(Map("id" -> Map(10 -> true))) // Other.
d(Map.empty) // Not found.

请注意,只有在调用该方法时Map的所有元素都具有相同的类型时,这才起作用...
如果首先使用Map[String, Any],这将变得更加复杂-也许Dmitry的答案会更好。