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!