over 6 years ago

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())
← iOS Swift : Function iOS Swift : Enumerations →