1. 佔位符 _html
針對 Scala 基礎(7)—— 函數字面量和一等函數 中最後提到的,關於 filter 函數字面量的精簡寫法,可使用佔位符 _ 來代替。java
佔位符_,用來表示一個或者多個參數。(這裏的多個參數不是表示一個下劃線表明多個參數,而是多個下劃線能夠表明多個參數)app
在函數字面量的表達中,能夠將下劃線當作是「要填的空」,函數每次被調用時,這個「空」就回被一個參數「填」上。函數
例如:post
def main(args: Array[String]): Unit = { val list = List(1, 2, 3) list.filter(x => x > 0) list.filter(_ > 0) // 與上面的調用是等價的 }
這種調用僅限於 Scala 編譯器可以在編譯期間推斷出參數的類型。url
當編譯器沒法再編譯期間推斷參數類型,則必須顯式地給出參數類型。spa
例如:htm
def main(args: Array[String]): Unit = { // val sum = _ + _ // 編譯失敗 val sum = (_: Int) + (_: Double) println(sum(1,2)) // 輸出3.0 }
2. 部分應用函數blog
在使用下劃線時,本質上是在編寫一個部分應用函數(partially applied function)。get
這裏的意義在於:
當調用某個函數,傳入任何參數時,其實是應用那個函數到這些參數上。
固然這種描述過於抽象,因此咱們看下面的例子:
首先,定義一個方法 sum():
def sum(a: Int, b: Int, c: Int) = a + b + c
顯然,這是一個計算三個整數和的方法。通常的調用方式以下:
val value = sum(1, 2, 3)
以上是一個簡單的方法的調用,部分應用函數的功能,就是將 def 定義的方法,映射成函數值的形式。
例如:
val f = sum _ // f 是一個 (Int, Int, Int) => Int 類型的函數字面量
以上,將方法映射成了一個 (Int, Int, Int) => Int 類型的函數字面量。
它的調用方式與方法相似,可是本質發生了改變:
val value = f(1, 2, 3)
之因此稱爲部分應用函數,是由於你並無把那個函數應用到全部的入參。
仍是拿上面的例子作說明,能夠經過給出一些必填的參數來表達一個部分應用函數:
val f = sum(1, _: Int, 2) // f 是一個 Int => Int 類型的函數字面量
在這個例子中,部分應用函數給出了第一個和第三個參數,因爲只缺失一個參數,編譯器將生成一個新的函數字面量,類型是 Int => Int。
部分應用函數的做用在於:
雖然不能將方法或嵌套的函數直接賦給某個變量,或者做爲某個函數的入參,可是能夠經過部分應用函數的方式,將其轉成一個函數值來完成這些操做。
最後須要說明的是,只有明確須要函數的地方,才能使用部分應用函數。