2017-02-26 94 views
1

我正在使用返回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 { 
         ^

不知道我在做什么错在这里。

回答

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())