[Swift]Closure, Trailing Closure, Shorthand Argument Names, @escaping

Penny N.
Apr 20, 2020

--

Photo by Jess Bailey on Unsplash

最近寫程式常常遇到closure,每當以為自己快要跟它當好朋友的時候卻又發現,不,我們一點也不熟,只好翻出之前的學習筆記來溫習一下。

這篇來簡單說明function如何簡化成closure。

Function

一般在宣告function時,會有func keyword、function name,也可能會有input parameter、input parameter type、return type。

初學者較少見的是,function的parameter及return type也可以是function。

將Function做為參數

宣告一個function calculator當範例,它能夠執行將兩個parameter相加的運算,並回傳結果。

但假如希望這個calculator的運算規則能夠從相加改成相乘時,必須要回到function中修改return的內容。

為了讓程式更方便、容易維護,這時候我們也可以讓原本的calculator中加入一個function參數,讓呼叫calculator時,由這個傳入calculator的function來決定calculator會執行什麼樣的運算規則。

return的部分則改寫成operation(n1, n2),意即將parameter n1、n2傳入operation function中。

而這個在宣告calculator時,operation的data type則必須與欲傳入的function的格式和參數型別相同。

因為function add有兩個parameter,兩個parameter及return的型別都是Int,所以operation也同樣有兩個parameter與return value,型別也都是Int。

用Closure簡化程式

Closure是沒有名字的function。如果這個要傳入function calculator作為argument的function add不會其他地方被呼叫,則可以將它簡化成closure,不必再額外宣告一個function add。

按照以下步驟,就可以將原本的function add改寫成一個closure,並且傳入function calculator。

func add(no1: Int, no2:Int) -> Int { 
return no1 + no2
}
  1. 刪掉keyword func
  2. 刪掉程式名字add
  3. 將第一個大括號{移到最前面
  4. 在原本大括號的地方加上keyword in
{(no1: Int, no2:Int) -> Int in
return no1 + no2
}

接著在呼叫calculator時,將簡化成closure的那串code丟進calculator的operation做為它的argument。

此時calculator所得到的運算和之前仍然相同。

進一步簡化程式

Swift可以自己偵測到data type,所以可以移除說明closure中parameter型別的Int。Swift也會自己推斷no1 + no2是要回傳的值,因此也可以省略return。

  1. 省略closure中的參數型別
  2. 省略closure中的keyword return

Trailing Closure

在Swift中,如果function最後一個parameter是個closure,那麼那個parameter name operation可以被省略,變成trailing closure。

  1. 省略closure的parameter name operation
  2. 小括號)移到closure的大括號{

沒有名字的parameter:$0、$1

Closure中parameter的名字也可以省略,改成用$0代表是第1個parameter,$1代表第2個parameter。

@escaping

一般做為argument傳入function的function在function執行完畢後就會隨著消失,例如下圖傳入completion的function若沒有加上@escaping就會在func fetchImage執行完畢後跟著消失,但加上了@escaping,就可以讓傳入completion的這個function在func fetchImage執行完畢後仍然繼續存活執行它的功能。

例如搭配URLSession就是需要使用@escaping的常見時機,它讓completion的function在function fetchImage這個執行完畢後還能繼續使用。

Pros and Cons

Closure的優點是可以徹底簡化原本需要撰寫多行的code,但同時也犧牲掉了程式的可讀性,讓對於swift不那麼熟悉的人不容易理解這行code的意義。

--

--

Penny N.
Penny N.

Written by Penny N.

A passionate self-taught  iOS developer. Write to record my learning and share the knowledge

No responses yet