Swift函數類型
函數類型(Function Types)
每個函數都有種特定的函數類型,由函數的參數類型和返回類型組成。
例如:
func addTwoInts(a: Int, b: Int) -> Int {
return a + b
}
func multiplyTwoInts(a: Int, b: Int) -> Int {
return a * b
}
這個例子中定義了兩個簡單的數學函數:addTwoInts 和 multiplyTwoInts。這兩個函數都傳入兩個 Int 類型, 返回一個合適的Int值。
這兩個函數的類型是 (Int, Int) -> Int,可以讀作「這個函數類型,它有兩個 Int 型的參數並返回一個 Int 型的值。」。
下面是另一個例子,一個沒有參數,也沒有返回值的函數:
func printHelloWorld() {
println("hello, world")
}
這個函數的類型是:() -> (),或者叫「沒有參數,並返回 Void 類型的函數」。沒有指定返回類型的函數總返回Void。在Swift中,Void 與空的元組是一樣的。
使用函數類型(Using Function Types)
在 Swift 中,使用函數類型就像使用其他類型一樣。例如,你可以定義一個類型爲函數的常量或變量,並將函數賦值給它:
var mathFunction: (Int, Int) -> Int = addTwoInts
這個可以讀作:
「定義一個叫做 mathFunction 的變量,類型是‘一個有兩個 Int 型的參數並返回一個 Int 型的值的函數’,並讓這個新變量指向 addTwoInts 函數」。
addTwoInts 和 mathFunction 有同樣的類型,所以這個賦值過程在 Swift 類型檢查中是允許的。
現在,你可以用 mathFunction 來調用被賦值的函數了:
println("Result: \(mathFunction(2, 3))")
// prints "Result: 5"
有相同匹配類型的不同函數可以被賦值給同一個變量,就像非函數類型的變量一樣:
mathFunction = multiplyTwoInts
println("Result: \(mathFunction(2, 3))")
// prints "Result: 6"
就像其他類型一樣,當賦值一個函數給常量或變量時,你可以讓 Swift 來推斷其函數類型:
let anotherMathFunction = addTwoInts
// anotherMathFunction is inferred to be of type (Int, Int) -> Int
函數類型作爲參數類型(Function Types as Parameter Types)
你可以用(Int, Int) -> Int這樣的函數類型作爲另一個函數的參數類型。這樣你可以將函數的一部分實現交由給函數的調用者。
下面是另一個例子,正如上面的函數一樣,同樣是輸出某種數學運算結果:
func printMathResult(mathFunction: (Int, Int) -> Int, a: Int, b: Int) {
println("Result: \(mathFunction(a, b))")
}
printMathResult(addTwoInts, 3, 5)
// prints "Result: 8」
這個例子定義了 printMathResult 函數,它有三個參數:第一個參數叫 mathFunction,類型是(Int, Int) -> Int,你可以傳入任何這種類型的函數;第二個和第三個參數叫 a 和 b,它們的類型都是 Int,這兩個值作爲已給的函數的輸入值。
當 printMathResult 被調用時,它被傳入 addTwoInts 函數和整數3和5。它用傳入3和5調用 addTwoInts,並輸出結果:8。
printMathResult 函數的作用就是輸出另一個合適類型的數學函數的調用結果。它不關心傳入函數是如何實現的,它只關心這個傳入的函數類型是正確的。這使得 printMathResult 可以以一種類型安全(type-safe)的方式來保證傳入函數的調用是正確的。
函數類型作爲返回類型(Function Type as Return Types)
你可以用函數類型作爲另一個函數的返回類型。你需要做的是在返回箭頭(->)後寫一個完整的函數類型。
下面的這個例子中定義了兩個簡單函數,分別是 stepForward 和stepBackward。stepForward 函數返回一個比輸入值大一的值。stepBackward 函數返回一個比輸入值小一的值。這兩個函數的類型都是 (Int) -> Int:
func stepForward(input: Int) -> Int {
return input + 1
}
func stepBackward(input: Int) -> Int {
return input - 1
}
下面這個叫做 chooseStepFunction 的函數,它的返回類型是 (Int) -> Int 的函數。chooseStepFunction 根據布爾值 backwards 來返回 stepForward 函數或 stepBackward 函數:
func chooseStepFunction(backwards: Bool) -> (Int) -> Int {
return backwards ? stepBackward : stepForward
}
你現在可以用 chooseStepFunction 來獲得一個函數,不管是那個方向:
var currentValue = 3
let moveNearerToZero = chooseStepFunction(currentValue > 0)
// moveNearerToZero now refers to the stepBackward() function
上面這個例子中計算出從 currentValue 逐漸接近到0是需要向正數走還是向負數走。currentValue 的初始值是3,這意味着 currentValue > 0 是真的(true),這將使得 chooseStepFunction 返回 stepBackward 函數。一個指向返回的函數的引用保存在了 moveNearerToZero 常量中。
現在,moveNearerToZero 指向了正確的函數,它可以被用來數到0:
println("Counting to zero:")
// Counting to zero:
while currentValue != 0 {
println("\(currentValue)... ")
currentValue = moveNearerToZero(currentValue)
}
println("zero!")
// 3...
// 2...
// 1...
// zero!