2017-01-09 78 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優選用於返回單元的代碼。