Swift 入門指南 V1.00 - 單元 8 - 閉包




每一種語言的閉包 (closure) 概念都不太一樣, Swift 的閉包簡單說是種匿名函數 (anonymous function) ,基本的閉包運算式 (closure expression) 如下圖



例如上個單元提過的 mathFunction() ,其中第一個參數 (parameter) 為函數 (function)


func mathFunction(f: (IntInt) -> Int, a: Int, b: Int) {
   println("The result is \(f(a, b)).")
}

這個需要函數的參數就可以用閉包代入,例如


mathFunction({(p1: Int, p2: Int) -> Int in
   return p1 + p2
}, 25, 63)

此閉包需要 p1p2 兩個 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: (IntInt) -> 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

沒有留言: