昨天介紹了函式常量跟函式值的應用,還有如何精簡地表示它們
今天要來介紹部分套用函式(Partially applied functions)
先來看以下的程式:
def product(x: Int, y: Int, z: Int) = x * y * z
product(1, 2, 3) //Output = 6
這是一個簡單的求三個數相乘的函式
另外在Scala裡,當我們呼叫一個有參數的函式時,我們其實是在對那個參數套用函式。
因此,當所有參數都傳給函式時,我們對所有參數完全套用了函式。
但是當我們只給函式傳進少於它所需要的參數個數時,這樣的表達式就是部分套用函式(Partially applied functions)
如下:
def product(x: Int, y: Int, z: Int) = x * y * z
val a = product _
a(2, 3, 4) //Output = 24
Scala編譯器會把a(2, 3, 4)
看成是對函式值的apply方法調用
也就是說a(2, 3, 4)
是
a.apply(2, 3, 4)
的簡寫
再來看另一個例子
val b = product(2, _, 4)
b(10) //Output = 80
//b.apply 呼叫 sum(2, 10, 4)
這邊我們提供了第一個跟最後一個引數給product
,缺少第二個。
所以Scala編譯器這時會生成一個新函式包含只接收一個引數的apply方法
當只用那一個引數呼叫時,這個新生成的函式的apply方法會去呼叫product
,並依序傳進第一個引數、傳給新函式的引數以及第三個引數。
當我們在操作HTML時可能會有個方法用來把前綴(prefix)、後綴(suffix)加進HTML片段,例如:
def wrap(prefix: String, html: String, suffix: String) =
prefix + html + suffix
如果對於不同的HTML我們都想要加進相同的前綴和後綴,那我們可以對方法套用那兩個前綴後綴參數,不套用HTML參數,如:
val wrapWithDiv("<div>", _, "<div>")
在談閉包之前,我們要先來說說自由變數(free variable)和綁定變數(bound variable)。
先來看以下函式:
(x: Int) => x + increase
在這個情況下,increase
是一個自由變數,因為函式常量並沒有賦予它任何意義
相比之下,x
就是一個綁定變數,因為在函式裡它有明確的定義:Int參數
。
val increase = 1
val more = (x: Int) => x + increase
more(10) //Output = 11
簡單來說,閉包指的是捕獲了自由變數的函式物件,之所以叫做“閉包”是因為它在創建時包住了當時可見的變數。
今天就介紹到這邊