Closures 代表具有功能性且可以被當作參數傳遞的程式區段,
之前提到的 function 就是 closures 的一種類型,屬於有命名且無法儲存值的 closures。
這篇主要講解的 closures 類型是是沒有命名且可以儲存值。
宣告與簡化
基本宣告方法。
{ (para: String) -> String in
return para
}
如果 body 只有一行的話。
{ (para: String) -> String in return para }
如果 closure 當作參數傳遞,因為 swift 會推斷參數的型別,所以可以省略參數與回傳值的型別定義。
{ para -> in return para }
如果 closure 只有一行的話,return 可以省略。
{ para -> in para }
如果 body 使用到參數來執行且只有一行,可以使用系統定義的 $0,$1 等參數名稱並且省略 in。
{$0}
Closure 傳遞
將 closure 當作 function 的參數傳遞。
沒有參數與回傳值。
func myFunc (closure: () -> Void) {
}
self.myFunc{
}
有參數。
func myFunc (closure: (_ para: String) -> Void) {
}
self.myFunc { (para) in
}
有回傳值。
func myFunc (closure: () -> String) {
}
self.myFunc { () -> String in
}
以上的 sample 都是呼叫時將 closure 放置到最後面,也可以照原本帶入參數的方法將 closure 放在括號內,
以下 sample 是兩種不同的方式。
func myFunc(para: Int closure: (_ para:String)->Void) {
}
self.myFunc(para:123 closure: { (para) in
})
self.myFunc(para:123) { (para) in
}
擷取值
之前有提到在 function 內定義 function,這個部分跟在 function 內定義 closure 相同,
在 function 內宣告的變數或常數,可以被 function 內的 closure 來使用。
func myFunc(para: Int) -> () -> Int {
var result = 0
return { () -> Int in
result += para
return result
}
}
self.myFunc(para: 123)()
Closures 是 reference types
跳脫 closures
在 function 內使用 closure 型別參數時,都必須要使用呼叫,
若是需要等到整個 function 結束後才進行呼叫,
例如在另外一個 closure 內執行或是放到 array 內之後執行,
參數前面需要加上 @escaping。
func myFunc(closure: @escaping () -> Int) -> () -> Int {
return closure
}
自動轉 closures
如果在 function 內宣告一個 closure 型別參數的時候,並且在參數前面加上 @autoclosure,
這時參數可以直接帶進來 closure 回傳值,會自動轉成 closure 型別。
func myFunc(closure: @autoclosure () -> int) {
}
func closureTest() -> Int {
return 123
}
myFunc(closure: closureTest())