正好前段时间在发力理解函数式编程,学习 Swift 至今就想看看 Swift 对函数式编程的支持如何。从变量声明用 let, 以及函数参数的 let 和 var 都非常适合于函数式编程,它们对实例保护的很好。let 和 var 类型的函数参数保证了函数内部操作的是传入参数的深拷贝。
在 Objective-C 中要调用一个函数,除了通过对像为媒介,还能 perform 一个 selector, selector 其实也是定位函数的方式,这更像是反射。其实 C/C++ 的函数指针概念更不错,用于直接定位函数。
所以进一步,函数要成为第一等公民,它本身可以很容易的作为参数传入或作为返回值,即能构成高阶函数。这在 Swift 也是没问题的,我们可以定义函数类型的变量,例如:
1 2 3 4 5 6 7 8 9 10 11 12 |
func addTwoInts(a: Int, _ b: Int) -> Int { return a + b } var addFunction: (Int, Int) -> Int = addTwoInts //addTwoInts 函数类型表示 (Int, Int) -> Int print(addFunction(1, 2)) let add = addTwoInts //自动推断出 add 函数的类型 func foo() { print(123) } let f:()->Void = foo |
从上面我们要理解函数类型的表示方式,参数列表到结果的映射, 空参数无返回值就表示为 ()->Void;并且从上懂得了通过函数变量如果调用函数,和 Javascript 一样的,就是后面直接加括号,带参数就行。
注意上面的 addTwoInts(a: Int, _ b: Int) 第二个参数的外部参数名可省略,不然调用 addFunction(1, 2) 时同样要写成 addFunction(1, b: 2)。同时它的 selector 表示法是 addTwoInts(_:, _:)。
有了现在的前提,搞清楚了函数类型的表示法,我们就可以构造出高阶函数,即函数怎么作为参数或怎么返回一个函数
函数作为参数
1 2 3 4 5 6 7 8 |
func addTwoInts(a: Int, b: Int) -> Int { return a + b } func printMathResult(mathFunction: (Int, Int) -> Int, _ a: Int, _ b: Int) { print("Result: \(mathFunction(a, b))") } printMathResult(addTwoInts, 3, 5) //输出 8 |
返回函数
1 2 3 4 5 6 7 8 9 |
func step(input: Int) -> Int { return input + 1 } func stepFunction() -> (Int)->Int { //这里出现两个 ->,写成 func stepFunction() -> ((Int)->Int) { 好看些 return step } stepFunction()(100) //值为 101 |
嵌套函数
函数可以嵌套定义,像 Javascript 那样
1 2 3 4 5 6 7 8 |
func stepFunction(steps: Int) -> ((Int)->Int) { func step(input: Int) -> Int { return input + steps } return step } stepFunction(5)(100) //值为 105 |
例子中我们又稍稍往前踏了一步,这的确嵌套函数的定义,并且内部函数捕获了一个外部变量,也是一个闭包。我们仍然是用 func 先定义好 step 函数再用 return step 返回,那么我们能不能像 Javascript 那样返回一个匿名的函数呢?类似 Javascript 的
1 |
return function(x, y) { return x + y;} |
那要立即上手一下 Swift 的 Lambda 语法
{ (parameters
) -> return type
in
statements
}
于是前面的嵌套函数可以写成
1 2 3 4 5 6 7 |
func stepFunction(steps: Int) -> ((Int)->Int) { return {input in //这行是省略写法 return input + steps } } stepFunction(20)(100) //值为 120 |
上方代码第一个 return 行中是省略写法,可以写成以下三种形式
return { (input) -> Int in
return { (input: Int) in
return { (input: Int) -> Int in
参考:Functions
本文链接 https://yanbin.blog/swift-learning-function-first-class/, 来自 隔叶黄莺 Yanbin Blog
[版权声明] 本文采用 署名-非商业性使用-相同方式共享 4.0 国际 (CC BY-NC-SA 4.0) 进行许可。