2017-01-09 88 views
0

我有以下斯卡拉功能:斯卡拉地图铸造的问题:类型mistmatch

def processMaps(toProcess : Map[Object,Object]) : Unit = { 
    // The 'toProcess' map might have a key named 'innerMap' which is itself a Map[String,String] 
    // Compiler Error: type mismatch; found : Object required: (String, String) 
    val innerMap : Map[String,String] = if (toProcess.containsKey("innerMap")) Map(toProcess.get("innerMap")) else null 

    // Do stuff to 'innerMap'... 
} 

的问题是innerMap声明产生以下编译器错误:

type mismatch; found : Object required: (String, String)

任何想法,为什么和什么修复是?

回答

1

toProcess.get("innerMap")返回一个对象,你要创建一个地图[字符串,字符串]从一个对象,那是没有意义的

你可以(但你不应该,因为它可以扔在运行时异常)强制类型转换有:

toProcess.get("innerMap").asInstanceOf[Map[String, String]] 

有在你的代码的几个细节,都不是最好的:

  1. 一个Map[Object,Object]?你应该使关键和值更具体的类型。为什么你有这样的通用类型?你在混合非常不同的类型吗?这不是惯用的斯卡拉。至少有一个地图[字符串,地图]
  2. 如果它是一个斯卡拉地图(而不是Java地图),Map.get方法将返回Option。你可以做.getOrElse(defaultValue),或者代替Map.get做一个Map.getOrElse(key, defaultValue)
  3. 斯卡拉避免使用null s。相反,它使用Option封装可能所没有的值,然后典型(单子)的功能类似于.map应用一些功能/行为如果该值是本
0
这里

是另一种可能的解决方案。模式匹配是你的朋友,避免asInstanceOf感觉有点脆弱。

def processMaps(toProcess : Map[Object,Object]) : Unit = { 
    val maybeObject: Option[Object] = toProcess.get("innerMap") 
    maybeObject.foreach { 
     case inner: Map[String, String] => // do some stuff to inner 
     Unit 
     case _ => // do nothing 
     Unit 
    } 
} 

甚至更​​少的代码

def processMaps(toProcess : Map[Object,Object]) : Unit = { 
    toProcess.get("innerMap").foreach { 
     case inner: Map[String, String] => // do some stuff to inner 
     case _ => // do nothing 
    } 
} 

几件事情在这里。

  1. 使用模式匹配是不容易出错
  2. 的foreach优选用于返回单元的代码。