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中相当于一个空元组,显示为()。
?
使用函数类型
在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
?
作为形参类型的函数类型
您可以使用一个函数类型,如(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被调用时,它传递addTwoInt函数,以及整数值3和5。它使用3和5调用了提供的函数,打印的结果是8。
?
printMathResult的作用是打印调用适当类型的数学函数的结果。该函数真正实现了什么并不重要--它只关心函数的类型是正确的。这使得printMathResult以一种安全类型的方式把自身的功能转换至函数的调用者。
作为返回类型的函数类型
你可以将一个函数类型作为另一个函数的返回类型。你可以在返回函数的返回箭头(->) 后立即编写一个完整的函数类型来实现。
?
下面的例子定义了两个简单的函数调用stepForward和stepBackward。stepForward函数返回一个输入值+1的结果,而stepBackward函数返回一个输入值-1的结果。这两个函数都有一个相同的(Int) -> Int类型 :
- func stepForward(input: Int) -> Int {
- return input + 1
- }
- func stepBackward(input: Int) -> Int {
- return input - 1
- }
?
这里有一个chooseStepFunction函数,它的返回类型是函数类型(Int) -> Int。chooseStepFunction基于名为backwards的布尔形参返回stepBackward或stepForward函数:
- 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变量趋于零。currentValue的初始值为3,这意味着currentValue > 0返回为真,并且chooseStepFunction返回stepBackward函数。返回函数的引用存储在一个名为moveNearerToZero的常量里。
?
如今moveNearerToZero执行了正确的功能,就可以用来计数到零:
- println(Counting to zero:)
- // Counting to zero:
- while currentValue != 0 {
- println((currentValue)... )
- currentValue = moveNearerToZero(currentValue)
- }
- println(zero!)
- // 3...
- // 2...
- // 1...
- // zero!
?
嵌套函数
迄今为止所有你在本章中遇到函数都是全局函数,在全局作用域中定义。其实你还可以在其他函数体中定义函数,被称为嵌套函数。
?
嵌套函数默认对外界是隐藏的,但仍然可以通过它们包裹的函数调用和使用它。enclosing function也可以返回一个嵌套函数,以便在其他作用域中使用嵌套函数。
?
你可以重写上面的chooseStepFunction例子使用并返回嵌套函数:
- func chooseStepFunction(backwards: Bool) -> (Int) -> Int {
- func stepForward(input: Int) -> Int { return input + 1 }
- func stepBackward(input: Int) -> Int { return input - 1 }