closure expression

閉包表達式(closure expression)是一種利用簡潔語法建立匿名函式的方式。同時也提供了一些優化語法,可以使得程式碼變得更好懂及直覺。閉包表達式的格式如下:
{ (參數) -> 返回值型別 in
內部執行的程式
}
上述程式中可以看到,與函式相同是以大括號{}將程式包起來,但省略了名稱,包著參數的小括號()擺到{}裡並接著箭頭->及返回值型別。然後使用in分隔內部執行的程式。
閉包表達式可以使用常數、變數和inout型別作為參數,但不能有預設值。也可以在參數列表的最後使用可變數量參數(variadic parameter)。元組也可以作為參數和返回值。
下面是一個例子,從將一個函式當做另一個函式的參數開始進行,原始程式碼如下:
// 這是一個要當做參數的函式 功能為將兩個傳入的參數整數相加並返回
func addTwoInts(number1: Int, number2: Int) -> Int {
return number1 + number2
}

// 建立另一個函式,有三個參數依序為
// 型別為 (Int, Int) -> Int 的函式, Int, Int
func printMathResult(
mathFunction: (Int, Int) -> Int, _ a: Int, _ b: Int) {
print("Result: \(mathFunction(a, b))")
}
這邊將函式addTwoInts()修改成一個匿名函式(即閉包)傳入,程式如下:
printMathResult({(number1: Int, number2: Int) -> Int in
return number1 + number2
}, 12, 85)
// 印出:97

/* 第一個參數為一個匿名函式(閉包) 如下
{(number1: Int, number2: Int) -> Int in
return number1 + number2
}
*/
上述程式中可以看到函式printMathResult()依舊為三個參數,第一個參數原本應該是一個函式,但可以簡化成一個閉包並直接傳入,其後為兩個Int的參數。
接下來會使用上面這個例子,介紹幾種優化語法的方式,越後面介紹的程式語法會越簡潔,但使用上功能是一樣的。

單表達式閉包隱式回傳

單行表達式閉包可以通過隱藏return來隱式回傳單行表達式的結果,修改如下:
printMathResult({number1, number2 in number1 + number2}, 12, 85)
// 印出:97

/* 第一個參數修改成如下
{number1, number2 in number1 + number2}
*/

參數名稱縮寫

Swift 自動為閉包提供參數名稱縮寫功能,可以直接以$0,$1,$2這種方式來依序呼叫閉包的參數。
如果使用了參數名稱縮寫,就可以省略在閉包參數列表中對其的定義,且對應參數名稱縮寫的型別會通過函式型別自動進行推斷,所以同時in也可以被省略,修改如下:
printMathResult({$0 + $1}, 12, 85)
// 印出:97

/* 第一個參數修改成如下
{$0 + $1}
*/

運算子函式

實際上還有一種更簡潔的語法。Swift 的String型別定義了關於加號+的字串實作,其作為一個函式接受兩個數值,並返回這兩個數值相加的值。而這正好與最一開始的函式addTwoInts()相同,因此你可以簡單地傳入一個加號+,Swift會自動推斷出加號的字串函式實作,修改如下:
printMathResult(+, 12, 85)
// 印出:97

// 第一個參數修改成: +
以上介紹了四種優化閉包的語法,使用上功能都與最一開始的閉包相同,所以可以依照需求以及合適性,使用不同的優化語法,來讓你的程式更簡潔與直覺,當然都使用完整寫法的閉包也是可以的