『Swift 5學習系列』-10. 進階函式

Shin Chao
6 min readJan 21, 2020

--

前面已經說明過什麼是函式(Function)了,那還要說什麼呢?其實function還有一些比較複雜的使用方式,這裡就來說一下進階的function功能。

【function也可以是一個型別】

function型別也是型別的一種,所以變數或常數除了可以宣告整數、浮點數等等…的型別外,也可以宣告是function的型別。所以function型別的變數或常數儲存的就是function了,那如何宣告呢?基本用法如下:

『var 變數名 : ( 型別 ) -> 型別 = function名稱』or
『var 變數名 = function名稱』 ✱ 因為Swift會自動判斷型別,所以可以省略型別
『let 常數名 : ( 型別 ) -> 型別 = function名稱』or
『let 常數名 = function名稱』 ✱ 因為Swift會自動判斷型別,所以可以省略型別

需要注意一點,如果宣告時的時候有帶function的型別,那型別必須與function名稱宣告的型別一致,不論是參數型別還是回傳型別都需要一樣,而且必須要連順序也都要相同,所以參數的個數也需要一樣,如果有其中一項不符合,那都會產生錯誤,所以想簡單點那就讓Swift自動判斷吧。

如果沒有傳入參數與回傳值時一樣要加上() -> (),不可以省略->(),因為這是Swift判斷是否為function型別使用的方式。

這邊有一個觀念要說一下,function名稱後面不需要加上小括弧(),如果加上小括號()就變成是呼叫function,沒加小括弧()則是指派function,兩者是完全不同的。

當呼叫這變數或常數時,也要傳入對應參數的值,由於呼叫這變數或常數的時候並不知道參數的名稱,所以不需要包含參數名稱。那如何使用呢?基本用法如下:

『變數名(參數值)』
『常數名(參數值)』

『範例說明』
3 - 5 : 定義一個叫做metersToFeet的function,這function有一個傳入型別為Double的參數meters,在第4行回傳一個Double型別的結果。
7 - 9 : 定義一個叫做feetToMeters的function,這function有一個傳入型別為Double的參數feets,在第8行回傳一個Double型別的結果。
10 : 宣告一個型別為Double的變數value,預計用來接收function回傳的計算結果。
11 : 宣告一個(Double)->(Double)的function型別的變數ans,並將metersToFeet指定給ans。
12 : 呼叫ans(),並傳入10,將回傳結果存入value。
13 : 印出”Ans is 32.8 feet.”。
14 :宣告一個function型別的常數,並將feetToMeters指定給result。
15 : 呼叫result(),並傳入10,將回傳結果存入value。
16 : 印出”Result is 3.048 meters.”。

【function也可以回傳function】

既然function也可以是一個型別,所以也可以當作另一個function的回傳值,其實只要記住兩個原則,第一個原則是箭頭的左邊是參數,箭頭的右邊則為回傳的型別,第二個原則是由左向右依序解讀。

『範例說明』
1 - 3 : 定義一個叫做steak的function,這function會回傳一個String型別的結果。
5 - 7 : 定義一個叫做seafood的function,這function會回傳一個String型別的結果。
9 - 15 : 定義一個叫做lottery的function,這function有一個傳入型別為Int的參數ball,判斷傳入參數是否大於10,大於時回傳stack這function,小於等於則回傳會回傳seafood這function。
17 : 宣告一個常數luckball,並將lottery回傳的function指定給luckball,lottery傳入的參數ball值為20,所以會跳到第10行,判斷ball是否大於10,因為參數是20,所以會回傳steak這個function。
18 : 宣告一個常數fate,並將luckball這function回傳的值指定給fate,所以fate的值為“贈送頂級和牛”。

【巢狀函式 (nested function)】

什麼是巢狀函式 (nested function)呢?其實就是function裡面還有定義其他的function。之前所說function都是定義在全域中,所以每個地方都可以使用與呼叫,但是巢狀函式 (nested function)因為是建立在function內,所以並無法讓外面呼叫,但可以當做回傳值,回傳後在其他的地方使用,例如function A內有一個function B,function B只能在function A內被呼叫。

『範例說明』
1 - 8: 定義一個叫做makeFood的function,這function有一個傳入型別為String的參數food,並回傳一個function。在這function內有一個processing的function,這function有一個傳入型別為String的參數name,並回傳一個String。
9 : 宣告一個常數cake,並將makeFood回傳的function指定給cake,makeFood傳入的參數food值為”蛋糕”,所以會跳到第6行,回傳processing這個function。
10 : 呼叫cake所被指定的function,並傳入參數”巧克力”,所以會呼叫到第2行,所以回傳的字串就是“巧克力蛋糕”。
11 : 呼叫cake所被指定的function,並傳入參數”花生”,所以會呼叫到第2行,所以回傳的字串就是“花生蛋糕”。

--

--