2011-08-22 84 views
4

我想過濾一個地圖從字符串到斯卡拉整數,我遇到了一個奇怪的問題。斯卡拉匿名功能的問題

如果我把下列REPL:

scala> val myMap = Map("a" -> 1, "b" -> 2, "c" -> 3) 
myMap: scala.collection.immutable.Map[java.lang.String,Int] = 
| Map(a -> 1, b -> 2, c -> 3) 

它的確定,到目前爲止,這個工程......

scala> myMap.filter(_._2 > 1) 
res9: scala.collection.immutable.Map[java.lang.String,Int] = Map(b -> 2, c -> 3) 

但失敗...

scala> myMap.filter((k:java.lang.String, v:Int) => v > 1) 
<console>:9: error: type mismatch; 
found : (java.lang.String, Int) => Boolean 
required: ((java.lang.String, Int)) => Boolean 
    myMap.filter((k:java.lang.String, v:Int) => v > 1) 

我的問題是錯誤信息和多餘的括號是怎麼回事?如果我嘗試添加一組額外的括號,則會出現錯誤:不是合法的形式參數。

回答

16

myMap.filter預計Tuple2[String, Int] => Boolean類型的函數,相當於((String, Int)) => Boolean。你傳遞給它一個類型爲(String, Int) => Boolean的函數;也就是說,一個函數需要兩個參數而不是一個Tuple2

兩種方式得到它的工作:通過(String, Int) => Boolean轉換功能((String, Int)) => Boolean

myMap.filter { case (k, v) => v > 1 } 

myMap.filter(Function.tupled((k, v) => v > 1)) 

通過模式匹配的首部作品,和第二。

順便說一下,有關於統一元組和函數參數列表的討論。也許在未來的Scala版本中,所有函數都將採用一個參數(可能是一個元組)。

+1

對於'Function.tupled'爲+1。 – agilesteel

+0

同意。 Function.tupled是顯式的,而模式匹配看起來更像是一個技巧。 – andyczerwonka

+1

對不起,如果這是一個愚蠢的問題,但爲什麼與大小寫匹配的模式使用花括號{}但不使用括號? –

6

filter接受只接受一個參數的函數。在您的表達式中,表達式接受兩個參數。然而,元素碰巧是一對,所以你可能會認爲你可以給出兩個參數。把它的正確的方法是這樣的:

myMap.filter (p => p._2 > 1) 

也就是說,我收到一對,p,它的第二個元素必須大於1。