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!