每一種語言的閉包 (closure) 概念都不太一樣, Swift 的閉包簡單說是種匿名函數 (anonymous function) ,基本的閉包運算式 (closure expression) 如下圖
例如上個單元提過的 mathFunction() ,其中第一個參數 (parameter) 為函數 (function)
func mathFunction(f: (Int, Int) -> Int, a: Int, b: Int) { |
println("The result is \(f(a, b)).") |
} |
這個需要函數的參數就可以用閉包代入,例如
mathFunction({(p1: Int, p2: Int) -> Int in |
return p1 + p2 |
}, 25, 63) |
此閉包需要 p1 跟 p2 兩個 Int 參數,最後回傳 p1 + p2 ,注意關鍵字 (keyword) in 必須放在回傳值 (return value) 之後。
可以採取簡化的的寫法,例如型態名稱可以省略
mathFunction({p1, p2 in return p1 + p2}, 26, 63) |
其實 return 也可以省略
mathFunction({p1, p2 in p1 + p2}, 27, 63) |
或是採用 $0 代表第一個參數, $1 表示第二個參數
mathFunction({$0 + $1}, 28, 63) |
因為此例是回傳兩個參數相加,更簡單的是用運算子函數 (operator function) ,也就是一個加號
mathFunction(+, 29, 63) |
以上全部輸入 Playground ,結果如下
其中像是用 $0 、 $1 的方式可以寫在函數呼叫的小括弧後,不過這樣函數參數就要放在參數列的最後一個,例如下面把 mathFunction() 改成 mathFunction2()
func mathFunction2(a: Int, b: Int, f: (Int, Int) -> Int) { |
println("The result is \(f(a, b)).") |
} |
mathFunction2(30, 63) {$0 + $1} |
輸入到 Playground ,結果如下
這樣的好處是閉包需要寫多行程式碼的時候,例如陣列有個 map() 方法 (method) ,需要一個函數參數
let d = [ |
0: "零", 1: "一", 2: "二", 3: "三", 4: "四", |
5: "五", 6: "六", 7: "七", 8: "八", 9: "九"] |
let n = [32, 85, 101] |
let s = n.map { |
(var i) -> String in |
var output = "" |
while i > 0 { |
output = d[i % 10]! + output |
i /= 10 |
} |
return output |
} |
方法是專屬於物件 (object) 的函數,定義上跟函數極為相似。
上例是把 100 之類的數字換成一零一的國字,留意這一行
output = d[i % 10]! + output |
因為這裡 d[i % 10]! 從 d 中取出的值會是選擇型態 (optional type) ,加上 ! 才能夠利用該字典 (dictionary) 的值。
輸入 Playground ,結果如下
下個單元繼續討論如何設計型態 (type) ,也就是定義自己的列舉 (enumeration) 、結構 (structure) 與類別 (class) 。
中英文術語對照
閉包 | closure |
匿名函數 | anonymous function |
閉包運算式 | closure expression |
參數 | parameter |
函數 | function |
關鍵字 | keyword |
回傳值 | return value |
運算子函數 | operator function |
方法 | method |
物件 | object |
選擇型態 | optional type |
字典 | dictionary |
型態 | type |
列舉 | enumeration |
結構 | structure |
類別 | class |
沒有留言:
張貼留言