2013-02-14 53 views
1

我想在Scala中編譯簡單的helloworld, 並獲得錯誤「scala:value capitalize is not char of member」 爲什麼編譯器認爲newW是Char?Scala:映射字符串時出現錯誤的類型推斷?

val dict = Map(
    "hello" -> "olleh", 
    "world" -> "dlrow" 
) 

def translate(input: String): String = { 
    input.split("""\s+""").map(w => dict.getOrElse(w.toLowerCase, w).map(newW => 
    (if (w(0).isUpper) newW.capitalize else newW)) 
).mkString(" ") 
} 

回答

3

translatemap第二個電話是對面dict.getOrElse(...)返回的值,其類型爲String,它可以作爲一個Iterable[Char]被隱式處理映射。因此,編譯器正確地推斷出newW的類型爲Char,並且當您嘗試對其調用capitalize時抱怨。你可能尋找的東西沿着

def translate(input: String): String = { 
    input.split("""\s+""").map(w => { 
    val newW = dict.getOrElse(w.toLowerCase, w) 
    (if (w(0).isUpper) newW.capitalize else newW) 
    }).mkString(" ") 
} 

更新的線路:順便說一句,這將在運行時失敗,如果input是一個空字符串 - 它需要安全的至少一個或多個檢查。

+0

從技術上講,不像Haskell,'String'不是'List [Char]'。我認爲他們之間有一個隱含的轉換。 – 2013-02-14 23:53:20

+0

你說得對,我已經相應地更新了文字。 – 2013-02-14 23:55:46

3

這裏發生的事情:

input // is a string 
.split("""\s+""") // is an Array[String] 
.map(w => // w is a String, for each String in the Array[String] 
    dict.getOrElse(w.toLowerCase, w) // is a String (returned by dict.getOrElse) 
    .map(newW => // is a Char, for each Char in the String returned by dict.getOrElse