全局函数是一个有名字但不会捕获任何值的闭包,它们是特殊得闭包
嵌套函数是一个有名字并可以捕获其封闭函数域内值得闭包
闭包表达式是一个利用轻量级语法所写得可以捕获上下文中变量或常量值得匿名闭包
前面介绍了全局函数和嵌套函数,今天我们来学习下闭包表达式
一、闭包引入
普通函数得写法
func ride(num:Int)->Int{
return num*num
}
print(ride(num:4))
闭包得写法
let fun = {
(num:Int)->Int in
return num*num
}
print(fun(8))
print(type(of:fun))//由此可以跑出fun的类型是:(Int) -> Int
闭包表达式语法
(1)是由一对{}来闭合包裹着这些代码
(2)in关键字把闭包分成两部分:
参数与返回值、闭包体
问题一:下面得代码是不是一个闭包
let fun2 = {
print("大家好")
}
print(type(of:fun2))//是一个闭包并且类型是:() -> ()
问题二:写一个闭包表达式,实现两数相加
let add = {
(num1:Int,num2:Int)->Int in
return num1+num2
}
print(add(4,6))
二、闭包的缩写
我们来定义一个数组里面存放一些学生的成绩,把大于某个阈值数来返回回来
func getscore(score:[Int],read:(Int)->Bool)->[Int]{
var arr = [Int]()
for item in score{
if read(item){
arr.append(item)
}
}
return arr
}
var score = [80,70,60,50,40,20]
print(getscore(score:score,read:{(s:Int)->Bool in return s>55}))
下面来学习一些闭包的简化
//省略1:省略->返回类型(自动推断返回类型是)
print(getscore(score:score,read:{(s:Int) in return s>40}))
//省略2:省略参数的类型,括号也可以省略(自动推断出参数的类型)
print(getscore(score:score,read:{s in return s>60}))
//省略3: 单行闭包表达式可以省略return关键字
print(getscore(score:score,read:{s in s>20}))
//省略4:省略参数列表定义,参数名称缩写用$0、$1、$3来表示调用闭包的参数,同时in关键字也可以省略。
print(getscore(score:score,read:{$0>50}))
三、尾随闭包
尾随闭包是一个书写在函数括号之后的表达式,
函数支持将其作为最后一个参数调用。
func lucky(info:String,Fun:(String)->Void){
Fun(info)
}
//1.普通的调用方式
lucky(info:"大家好",Fun:{x in print(x+"很高兴认识你")})
//2.尾随闭包的调用方式
lucky(info:"我爱"){x in print(x+"吃水果")}
四、值捕获
嵌套函数或者闭包可以在其定义的上下文中捕获常量或者变量,
即使定义的这些常量或者变量的原作用域已经不存,
任然可以在闭包函数体中引用或修改这些常量或者变量。
func makeArray(forIncrement amount: Int) -> () -> Int {
var runningTotal = 0
func incrementer() -> Int {
runningTotal += amount
return runningTotal
}
return incrementer
}
let a = makeArray(forIncrement:40)
print(a())
闭包是引用类型
let b = a
print(b())
let c = makeArray(forIncrement:20)
print(c())
五、逃逸闭包
逃逸闭包的书面定义:一个传入函数的闭包如果在函数执行结束之后才会被调用,那么这个闭包就叫做逃逸闭包。
逃逸闭包的特点:
1、可以在函数结束后使用;
2、寿命长!逃逸闭包声明周期长于函数,只要它的引用被其他对象持有,就不会随着函数结束而释放掉
3、通过@escaping 指定一个闭包是逃逸闭包
var recv:()->Void = {print("")}
var x = 10
func test(closure:@escaping ()->Void){
recv = closure
}
test{
x = 666
}
recv()
print(x)