将对象(Any)与Scala Map匹配的模式

时间:2017-02-26 00:37:42

标签: scala pattern-matching

我正在使用一个返回类型为Object的对象的Java库。现在我想模式匹配并获得适当的类型。我希望它是一个Java Map。所以,我尝试使用它:

scala> :paste
// Entering paste mode (ctrl-D to finish)

import scala.collection.JavaConverters._

val any: Any = new java.util.HashMap[Object, Object]

Option(any).flatMap {
  case x: java.util.Map[_, _] => Some(x.asScala.toMap)
  case x: Map[_, _] => Some(x)
  case _ => None
}

// Exiting paste mode, now interpreting.

<console>:17: error: no type parameters for method flatMap: (f: Any => Option[B])Option[B] exist so that it can be applied to arguments (Any => Option[scala.collection.immutable.Map[_,Any]] forSome { type _ })
 --- because ---
argument expression's type is not compatible with formal parameter type;
 found   : Any => Option[scala.collection.immutable.Map[_,Any]] forSome { type _ }
 required: Any => Option[?B]
       Option(any).flatMap {
                   ^
<console>:17: error: type mismatch;
 found   : Any => Option[scala.collection.immutable.Map[_,Any]] forSome { type _ }
 required: Any => Option[B]
       Option(any).flatMap {
                           ^

不确定我在这里做错了什么。

1 个答案:

答案 0 :(得分:1)

以下作品。编译器没有足够的信息来导出这里的类型,因为我们在模式匹配中使用了地图的存在类型。这是因为与Java不同Map不是scala中的类型,而Map[T,U]

Option(any).flatMap[Any]({
  case x: java.util.Map[_, _] => Some(x.asScala.toMap)
  case x: Map[_, _] => Some(x)
  case _ => None
})

如果我们不使用如下所示的存在类型,我们将能够使用没有指定显式类型参数的flatMap

scala> Option(any).flatMap({
     |   case x: java.util.Map[Int, Int] @unchecked => Some(x.asScala.toMap) // using Int as example to create a fully qualified type of Map
     |   case x: Map[Int, Int] @unchecked => Some(x) // using Int as example to create a fully qualified type of Map
     |   case _ => None
     | })
res5: Option[scala.collection.immutable.Map[Int,Int]] = Some(Map())