2015-09-28 51 views
1

我正在學習specs2測試框架,通過下面的一些例子。Scala使用部分應用程序的匿名函數語法?

我注意到下面的匿名函數的語法重複:

val upper = (_: String).toUpperCase 

這相當於更傳統的/一般

val upper = (s: String) => s.toUpperCase 

雖然語法簡單大方,但它的不是很familiar (easy)

有人能指導我瞭解第一種語法的工作原理/派生方法嗎?我很確定它與某種部分申請有關,但不能完全推理。

也是在Scala中經常使用的語法? (我還在這裏學習的繩索:])

編輯::

我已經找到了循環模式使用這樣的語法是特設多態(簡單地說,重載方法/功能),其中參數傳遞函數的類型決定了哪個函數被調度。

例如,

def f(g: Int => String): String = g(10) 
def f(g: String => String): String = g("hello") 
f((_: Int).toString + " beers") // 10 beers 
f((_: String) + " world") // hello world 

這種模式是在圖書館等重複ScalaCheck

回答

2

該語法根據參數順序指示您正在創建函數的編譯器,其參數的類型爲String,該參數插入使用_的地方。如果您有:

val f = (_:String).length + (_:Int) 

它會創建一個函數(String, Int) => Int,哪里哪里正在使用的每個_馬克參數。順序很重要!他們必須以相同的順序使用你想要的功能的參數是

如果類型已經定義聲明val時,你可以在函數體中忽略它們:

val f: (String, Int) => Int = _.length + _ 
+0

你的最後一句話讓一切明確。 '如果聲明val時已經定義了類型,則可以在函數體中省略它們'。儘管我很熟悉使用'_'來傳遞匿名函數給combinators,但是這個語法看起來令人毛骨悚然,因爲它創建的函數沒有預定義的類型。謝謝! –