闭包
闭包的结构
函数包含:函数名,参数列表,返回值,函数体。
闭包:{(参数列表) ->fan返回值 in 闭包体}
//标准函数
func myFunc(param: Int) -> Int{
return param * param
}
//闭包
let myClosures = {(param: Int) -> Int in
return param * param
}
myFunc(param: 3) //调用函数
myClosures(3) //调用闭包
闭包的返回值可以省略:
let myClosures1 = {(param: Int) in
return param * param
}
闭包实现冒泡排序
func mySort(array: inout Array<Any>, sortClosures: (Int, Int) ->Bool) -> Array<Any>{
for indexI in array.indices{
//最后一个元素直接返回
if indexI == array.count-1{
break
}
// 冒泡排序
for indexJ in 0...((array.count-1) - indexI - 1) {
//调用传递进来的闭包算法
if sortClosures(indexJ, indexJ+1){
}else{
array.swapAt(indexJ, indexJ+1)
}
}
}
return array
}
var array: Array<Any> = [1, 4, 3, 5, 7, 5, 4, 2, 7]
mySort(array: &array, sortClosures: {(index: Int, nextIndex: Int) ->Bool in
return (array[index] as! Int) > (array[nextIndex] as! Int)
}) //as!的作用是类型转换
print(array)
将闭包作为参数传递时的写法优化
1.省略返回值类型
2.省略return
3.省略参数
逃逸闭包,后置闭包,自动闭包
后置闭包:当函数中最后一个参数为闭包参数时,在调用函数时,将闭包结构脱离出函数的参数列表,追加到函数的尾部,增加代码的可读性。
//后置闭包
mySort(array: &stuArr) {
(stuArr[$0] as! Student).achievment > (stuArr[$1] as! Student).achievment
}
//原函数
func myFunc1(closure: (Int, Int) ->Bool){
}
//闭包后置
myFunc1{
$0 > $1
}
逃逸闭包:指函数内的闭包在函数执行结束后在函数外仍然可以进行使用。
非逃逸闭包:指当函数的生命周期结束后,闭包也会被销毁,也就是说当函数内部使用,在函数外部不能够使用。(默认情况下函数内闭包为非逃逸闭包)
非逃逸闭包不可以作为返回值返回
逃逸类型的闭包常用于异步操作,如:后台请求完成后要执行闭包回调,需要使用逃逸类型。
自动闭包:此闭包不能有参数,在调用函数传参时只能由一句表达式组成,闭包返回值为此表达式的值,由@autoclosure来声明。
//自动闭包
func myFunc2(closure : @autoclosure () ->Bool){
}
//调用函数时直接传入一个表达式即可,编译器会自动生成闭包
myFunc2(closure: 2+3+4>10)
//将闭包参数声明为自动闭包 逃逸闭包
func myFunc3(closure: @autoclosure @escaping () ->Bool){
}