let num = 1
func add(_ v:Int) -> (Int)->Int {
return {
$0 + v
}
}
var fn = add(3)
fn(20)
print(fn(20))
在上面代码中,我们定义了一个函数,该函数接收一个参数,返回一个函数,也算返回一个闭包var fn = add(3),这里的fn,就是add函数返回值,同时这个返回值也是一个函数,调用这个fn函数,fn(20),相当于就是调用了$0+v,所以得到的结果是23,这有什么好处呢,首先我们确定的一个就是最初的调用add(3),这里我们传入了3,那么这个三就算是固定了,那么后面所有的fn的调用,都传入了这个3,这个3就是当初传入的那个v,随后传入到了**(Int) -> Int中去了。
示例
var fn = add(3)
fn(20) // 23
fn(100) // 103
fn(97) // 100
fn(80) // 83
相当于fn这个函数,是可以循环利用的
let num = 1
func add(_ v:Int) -> (Int)->Int { { $0 + v } }
func sub(_ v:Int) -> (Int)->Int { { $0 - v }}
func multipe(_ v:Int) -> (Int)->Int { { $0 * v } }
func divide(_ v:Int) -> (Int) -> Int { { $0 / v } }
func mod(_ v:Int) -> (Int)-> Int { { $0 % v } }
let fn1 = add(3)
let fn2 = multipe(5)
let fn3 = sub(1)
let fn4 = mod(10)
let fn5 = divide(2)
print(fn5(fn4(fn3(fn2(fn1(num)))))) // 4
从调用的方式来看,可读性其实并不是很好print(fn5(fn4(fn3(fn2(fn1(num)))))),尝试一下看看能不能合并起来
func composite(_ f1:@escaping (Int) -> Int,_ f2:@escaping (Int) -> Int) -> (Int) -> Int{
return {
f2(f1($0)) // $0其实就是外界传进来的num值
// f1($0)其实就是add(3)(num)
// f2同理可推
}
}
let fn = composite(add(3), multipe(5))
fn(num)
这里的函数fn(num)调用,其实就是完成了(num+3)*5的操作
高阶函数
柯里化(Currying)
将一个接收多参数的函数变换为一系列直接收单个参数的函数
func add1(_ v1:int,_ v2:int) -> Int {
// 如何对这个函数进行柯里化
}
func add1(_ v:int) -> (Int) - Int {
return { a in
v + a
}
}
或者这么写
func add1(_ v:Int) -> (Int)->Int {
return {
$0 + v
}
}
进阶
func add2(_ v1:Int,_ v2:Int,_ v3:Int) -> Int {}
如何对这个函数进行柯里化
func add2(_ v:Int) -> (Int) -> (Int) -> Int {
// 如何对这个函数进行柯里化
}
func add2(_ v:Int) -> (Int) -> (Int) -> Int {
return { a in
return { b in
v + a + b
}
}
}
print(add2(10)(20)(30)) // 60
解析一下,add2接收一个参数,返回一个函数,而返回的这个函数中,接收一个参数,也返回一个函数,在第一个return中,其实return的是((Int) -> (Int) -> Int)这个函数,第二个return的,才是最后返回的函数(Int)->Int
func add(_ v1:Int,_ v2:Int) -> Int { v1+v2 }
func sub(_ v1:Int,_ v2:Int) -> Int { v1 - v2 }
func multipe(_ v1:Int,_ v2:Int) -> Int { v1*v2 }
func divide(_ v1:Int,_ v2:Int) -> Int { v1/v2 }
func mod(_ v1:Int,_ v2:Int) -> Int { v1%v2 }
func currying<A,B,C>(fn:@escaping (A,B) -> C) -> (B) -> (A) -> C {
return {
b in {
a in
fn(a,b)
}
}
}
print(currying(fn: addTest)(10)(20)). // 20 + 10
print(currying(fn: subTest)(10)(20)). // 20 - 10
print(currying(fn: multipeTest)(10)(20)). //20*10
print(currying(fn: modTest)(10)(20)). //20%10
print(currying(fn: divideTest)(10)(20)). //20/10