一个完整的函数包含函数名、参数列表、返回值和函数体,主要是为了实现代码块的复用。
闭包和函数有着类似的作用,然而闭包的设计大多数情况下并不是为了代码的复用,而是传递功能代码块和处理回调结构。
// 闭包可以省略->返回值类型
// 闭包
let bib = {(parama:Int) in
return parama*parama // 注意,在return中直接使用*要避免让编译器报错,如 return parama *parama
}
var blockC = {(num1:Int,num2:Int)->[Int] in
// 如果参数参与了除返回值表达式外的表达式,那么需要明确返回值类型
let a10 = num1 / 10
let a = num1 % 10
let b10 = num2 / 10
let b = num2 % 10
return [a10 * 1000 + b10 * 100 + b * 10 + a]
}
闭包作为函数参数时注意:
1. 省略参数使用 $X 来代替闭包参数,必须在作用域内将所有参数都表示出来,且必须省略in
后置闭包 (闭包作为函数最后一个参数时,可以部分省略以达到简洁美观的效果)
func sum (arrar:Array<Any>,sour:(Int,Int)->Bool){
sour(1,2)
}
var a:Array<Any> = [1,2,3,4,5]
// 省略参数
sum(arrar: a,sour: {
print(a[$0],a[$1])
return true
})
// 极简:省略参数直接在末尾用大括号表示,后置闭包的省略与标准的函数实现相同,要注意观察,可以看是否有$号,是否有返回值,但光从符号和返回值也不能判断
sum(arrar: a){
print(a[$0],a[$1])
return true
}
逃逸闭包和非逃逸闭包
所谓逃逸闭包,是指函数内的闭包在函数执行结束后在函数外依然可以进行使用,非逃逸闭包是指当函数的生命周期结束后,闭包也将被销毁。
@noescape 将闭包声明为非逃逸型,非逃逸型闭包不能作为函数的返回值,否则会报错
@autoclosure 自动闭包,常用于函数参数,不能传递参数,只能有一句表达式,返回值即表达式的值
func sum (sour:@autoclosure ()->Bool){
}
sum(sour: 1 > 2) // 不能缺少参数名
//@escaping 逃逸型闭包,可以做为函数的返回值
func myFunc2(closure: @autoclosure @escaping ()->Bool){
// 自动闭包+逃逸闭包
}
闭包作为参数的理解
func composeArr(arr:inout Array<Int>,com:(_ num1:Int,_ num2:Int)->Bool){
// 外循环:获取索引
for indexW in arr.indices {
// 最后一个元素直接返回
if indexW == arr.count - 1 {
continue
}
// 获取内循环元素
let SubArr = arr[indexW+1...arr.count-1]
for SubIndex in SubArr.indices {
let numW = arr[indexW]
let numN = arr[SubIndex]
// 符合条件不变
if com(numW,numN) {
}else{
// 不符合条件交换两元素位置
arr.swapAt(indexW, SubIndex)
}
}
}
}
var arr:Array<Int> = []
composeArr(arr: &arr) { (num1, num2) -> Bool in
return num1 > num2
}
//备注:第一个花括号为方法实现,调用的括号为block实现
// 数组中的index并非Int类型,通过截取的方式截取Index,遍历时的Index为原数组中的Index
网友评论