SwiftUI基础之闭包

  • 后置闭包、逃逸闭包与自动闭包

// 定义闭包,类似于 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!”

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容