将对象(任何)与Scala映射匹配的模式
问题描述:
我正在使用返回Object
类型的对象的Java库。现在我想模式匹配并获得适当的类型。我期望它是一个Java Map。所以,我试着用这个:将对象(任何)与Scala映射匹配的模式
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 {
^
不知道我在做什么错在这里。
答
下面的工作。编译器没有足够的信息来派生类型,因为我们在模式匹配中使用地图的存在类型。这是因为不同的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())