// 定义闭包,类似于 Kotlin 的 lambda 表达式。
// 闭包一般是为了处理回调,传递功能代码块
// 闭包标准语法结构:{(param list) -> valueType in block}
let closureFunc1 = {(param1: Int, param2: Int) -> Int in
return param1 + param2
}
// 调用闭包
closureFunc1(1, 2) // 3
// 闭包可省略返回值
let closureFunc2 = {(param1: Int, param2: Int) in
return param1 + param2
}
closureFunc2(1, 3) // 4
// 如果闭包只有一行代码,可以省略 return
let closureFunc3 = {(param1: Int, param2: Int) in
return param1 < param2
}
closureFunc3(1, 2) // true
// 入参为闭包
func func10(closureParam: (Int, Int) -> Bool) {
closureParam(2, 1)
}
// 使用默认参数名
func10(closureParam: { $0 > $1 }) // true
// 后置闭包,当最后一个参数为闭包时,简化写法:
func10() {
$0 > $1
}
// 非逃逸闭包:函数的生命周期结束后,闭包也将被销毁
// 定义的闭包默认都是非逃逸的
// 逃逸闭包:函数的执行结束后,闭包在函数外仍可使用
// 定义逃逸闭包使用 @escaping ,一般用于异步回调
func func11(closureParam: @escaping (Int, Int) -> Bool) {
}
// 定义自动闭包使用 @autoclosure,对简单闭包的自动生成。
// 自动闭包默认非逃逸。自动闭包不能够有参数,单表达式
func autoCloseFunc(closureParam: @autoclosure () -> Int) {
print(closureParam()) // 6
}
autoCloseFunc(closureParam: 1 + 2 + 3)
闭包和函数是引用类型
,将函数或闭包赋值给一个常量还是变量,实际上都是将常量或变量的值设置为对应函数或闭包的引用。
func makeInCount(count: Int) -> () -> Int {
var total = 0
func incrementer() -> Int {
total += count
return count
}
return incrementer
}
let incrementBySeven = makeInCount(count: 7)
incrementBySeven()
let alsoIncrementBySeven = incrementBySeven
alsoIncrementBySeven()
逃逸闭包
,当一个闭包作为参数传到一个函数中,但是这个闭包在函数返回之后才被执行,我们称该闭包从函数中逃逸。当你定义接受闭包作为参数的函数时,你可以在参数名之前标注 @escaping,用来指明这个闭包是允许“逃逸”出这个函数的。 例如网络请求
func request(result:@escaping((String)->())){
DispatchQueue.main.asyncAfter(wallDeadline: DispatchWallTime.now() + 10) {
result("数据结果")
}
}
非逃逸闭包
, 永远不会离开一个函数的局部作用域的闭包就是非逃逸闭包。
func player(complete:(Bool)->()){
complete(true)
}
自动闭包
,自动闭包是一种自动创建的闭包,用于包装传递给函数作为参数的表达式。这种闭包不接受任何参数,当它被调用的时候,会返回被包装在其中的表达式的值。当闭包作为参数传入 可用@autoclosure标记闭包参数 ,可将参数当函数调用而并非以闭包的形式。这种便利语法让你能够省略闭包的花括号,用一个普通的表达式来代替显式的闭包
var customersInLine = ["Chris", "Alex", "Ewa", "Barry", "Daniella"]
print(customersInLine.count)
// 打印出“5”
let customerProvider = { customersInLine.remove(at: 0) }
print(customersInLine.count)
// 打印出“5”
print("Now serving (customerProvider())!")
// 打印出“Now serving Chris!”
print(customersInLine.count)
// 打印出“4”
// customersInLine is ["Ewa", "Barry", "Daniella"]
func serve(customer customerProvider: @autoclosure () -> String) {
print("Now serving (customerProvider())!")
}
serve(customer: customersInLine.remove(at: 0))
// 打印“Now serving Ewa!”
//不用 @autoclosure 修饰
func serve(customer customerProvider: () -> String) {
print("Now serving (customerProvider())!")
}
serve(customer: { customersInLine.remove(at: 0) } )
//打印“Now serving Ewa!”