Scala地图投射问题:类型错误匹配

时间:2017-01-09 14:39:29

标签: scala compiler-errors type-mismatch

我有以下Scala函数:

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声明会产生以下编译器错误:

  

类型不匹配; found:需要对象:(String,String)

知道为什么以及解决方案是什么?

2 个答案:

答案 0 :(得分:1)

toProcess.get("innerMap")返回一个对象,你试图从一个对象创建一个Map [String,String],这是没有意义的

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

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

您的代码中有一些不是最好的细节:

  1. a Map[Object,Object]?你应该使键和值更具特定类型。为什么你有这样的通用类型?你在混合不同的类型吗?那不是惯用的Scala。至少有一个Map [String,Map]
  2. 如果它是Scala Map(而不是Java Map),Map.get方法将返回Option。您可以执行.getOrElse(defaultValue),或代替Map.get执行Map.getOrElse(key, defaultValue)
  3. Scala避免使用null s。相反,它使用Option来封装可能的不存在的值,然后使用典型的(monad)函数(如.map)来应用某些函数/行为(如果值存在)

答案 1 :(得分: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是返回Unit的代码的首选。