iT邦幫忙

2019 iT 邦幫忙鐵人賽

DAY 11
0

https://ithelp.ithome.com.tw/upload/images/20181026/20110801oexZeXz40N.png

尾隨閉包

如果需要將很長的閉包表達式作為最後一個參數傳遞給函式,使用尾隨閉包來增強函式的可讀性。尾隨閉包是寫在小括號後面的閉包表達式,函式支援將閉包作為最後一個參數做呼叫

func 函式名稱(內部參數名: () -> ()){
內部執行程式
}
//不使用尾隨閉包時呼叫function
函式名稱({
閉包內的程式
})
//閉包型別為:() -> () 沒有參數也沒有回傳值,可以看到閉包是作為參數放在()裡
//使用尾隨閉包時呼叫function
函式名稱(){
閉包內的程式
}
//如果函式只有閉包這一個參數,可以省略()
函式名稱 {
閉包內的程式
}

捕獲值

閉包可以在其定義的上下文中捕獲常數或變數,即便定義這些常數或變數的原使用區域已不在,閉包仍可以在閉包函式體內使用或修改這些值
Swift 中,可捕獲值最簡單形式是巢狀函數,也就是定義在其他函式中的函式。巢狀函式可以捕獲並存取外部函式內所有的參數及其鎖定亦得常數及變數,即使巢狀函數已回傳,導致這些常數或變數的做用已不在,閉包仍可對這些已捕獲的值做操作。

https://ithelp.ithome.com.tw/upload/images/20181026/201108017xmzyFyLcj.png

巢狀函式的內部存取了 runningTotal 及 amount 兩個變數,是因為他從外部函式捕獲了這兩個變數的參考,而這個捕獲參考會讓 runningTotal 及 amount 呼叫完 makeIncrementer 完後不會消失,並在下次呼叫 increment 時,runningTotal 仍存在

呼叫這個函式的方法:

https://ithelp.ithome.com.tw/upload/images/20181026/20110801Hj8RKKGZB7.png

在上面的呼叫中,可以驗證下次呼叫 function 時,runningTotal 仍存在的事實,因此再另外呼叫一次 incrementFive 及 incrementTen,重新驗證此說法

閉包是參考型別

上面的例子中,incrementTen 及 incrementFive 都是常數,但這些常數指向的閉包仍可以增加其捕獲的變數值

https://ithelp.ithome.com.tw/upload/images/20181026/20110801KVi2W4zcnw.png

逃逸閉包

當閉包作為參數傳遞給函式時,我們可以說這個閉包逃逸了,而它可以在函式回傳後被調用。當我們宣告一個函式的參數為閉包時,可以再參數的類型前面寫 @escaping 表示允許閉包逃逸。

閉包可以逃逸的一種方式為:被儲存定義於函數外的變數裡。

https://ithelp.ithome.com.tw/upload/images/20181026/20110801o7WU9xaDGM.png

newFunction 會接收一個閉包當做參數,並新增到我們在 function 外宣告的 Array 中,而我們讓閉包逃逸意味著要在閉包中用 self

https://ithelp.ithome.com.tw/upload/images/20181026/20110801v7SLbpCQrf.png

自動閉包

是一種自動被建立的閉包,用於包裝後傳遞給函式作為參數的表達式,這種閉包沒有參數,當被使用時,會回傳被包裝在裡面表達式的值。簡單來說,自動閉包是一種簡化後的語法,讓我們可以用普通的表達式代替顯式的閉包,進而省略了大括號{}。
自動閉包可以讓你延遲求值,我們可以控制程式何時才進行求值:

https://ithelp.ithome.com.tw/upload/images/20181026/20110801xq8pOU5xpX.png

我們刪除了 aArray 中的第一個元素,但在還沒調用 removeArray 時,aArray的數量仍是 6 個,也就是延遲求值,如果閉包永遠不被調用,那閉包裡的表達式就永遠不會求值

https://ithelp.ithome.com.tw/upload/images/20181026/201108014HkBuiejfo.png

今天的 Closure 就到這裡囉!如果有其他的問題歡迎留言或是寄信給我!(*´∀`)


上一篇
Swift4.2 Day-10 Closure ( 1 )
下一篇
Swift4.2 Day-12 Enumeration
系列文
菜比八iOS程式開發30天自我挑戰30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言