Swift4 闭包,例子代码

本文深入讲解Swift中的闭包概念,包括闭包表达式的语法、不同形式的闭包使用方法、闭包与函数参数的关系及自动闭包的应用。通过具体实例展示了如何使用闭包进行排序、数组元素处理等操作。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

闭包

苹果官方文档 闭包
苹果官方文档翻译 闭包
  • 闭包表达式

      { (parameters) -> (return type) in
        statements
      }     

    ##### Sorted 方法
    sorted(by:) 会根据你提供的排序闭包将已知类型的数组的值进行排序,返回排序后的新数组,原数组不变。

    let names = ["Chris","Alex","Ewa","Barry","Daniella"]
    
    func backward(_ s1: String, _ s2: String) -> Bool {
    return s1 > s2
    }
    var reversedNames = names.sorted(by: backward)
    // reversedNames is equal to ["Ewa", "Daniella", "Chris", "Barry", "Alex"]
    ##### 闭包表达版本
    reversedNames = names.sorted(by: { (s1: String, s2: String) -> Bool in return s1 > s2 })
    ##### 从语境中推断类型
    reversedNames = names.sorted(by: { s1, s2 in return s1 > s2 } )
    ##### 从单表达式闭包隐式返回
    reversedNames = names.sorted(by: { s1, s2 in s1 > s2 } )
    ##### 简写实际参数名
    reversedNames = names.sorted(by: { $0 > $1 } )
    ##### 运算符函数
    reversedNames = names.sorted(by: >)
  • 尾随闭包

    func someFunctionThatTakesAClosure(closure:() -> Void){
       //function body goes here
    }
    
    //here's how you call this function without using a trailing closure
    
    someFunctionThatTakesAClosure({
       //closure's body goes here
    })
    
    //here's how you call this function with a trailing closure instead
    
    someFunctionThatTakesAClosure() {
       // trailing closure's body goes here
    }

    如果闭包为函数唯一实参,并作为尾随闭包,可以省略括号

    reversedNames = names.sorted { $0 > $1 }
    let digitNames = [
    0: "Zero",1: "One",2: "Two",  3: "Three",4: "Four",
    5: "Five",6: "Six",7: "Seven",8: "Eight",9: "Nine"
    ]
    
    let strings = numbers.map {
        (number) -> String in
        var number = number
        var output = ""
        repeat {
            output = digitNames[number % 10]! + output
            number /= 10
        } while number > 0
        return output
    }
    // strings is inferred to be of type [String]
    // its value is ["OneSix", "FiveEight", "FiveOneZero"]
  • 捕获值

    func makeIncrementer(forIncrement amount: Int) -> () -> Int {
        var runningTotal = 0
        func incrementer() -> Int {
            runningTotal += amount
            return runningTotal
        }
        return incrementer
    }
    
    let incrementByTen = makeIncrementer(forIncrement: 10)
    
    incrementByTen()
      //return a value of 10
      incrementByTen()
      //return a value of 20
      incrementByTen()
      //return a value of 30
    
    let incrementBySeven = makeIncrementer(forIncrement: 7)
    incrementBySeven()
    // returns a value of 7
    
    incrementByTen()
    // returns a value of 40
  • 闭包是引用类型

    let alsoIncrementByTen = incrementByTen
      alsoIncrementByTen()
      //return a value of 50
  • 闭包逃逸

    闭包作为一个实际参数传递给一个函数的时候,我们就说这个闭包逃逸了。
    声明一个接受闭包作为形式参数的函数时,你可以在形式参数前写 @escaping 来明确闭包是允许逃逸的。
    var completionHandlers: [() -> Void] = [] func someFunctionWithEscapingClosure(completionHandler: @escaping () -> Void) { completionHandlers.append(completionHandler) }
    闭包 @escaping 意味着你必须在闭包中显式地引用 self
    ```
    func someFunctionWithNonescapingClosure(closure: () -> Void) {
    closure()
    }

    class SomeClass {
    var x = 10
    func doSomething() {
    someFunctionWithEscapingClosure { self.x = 100 }
    someFunctionWithNonescapingClosure { x = 200 }
    }
    }

    let instance = SomeClass()
    instance.doSomething()
    print(instance.x)
    // Prints "200"

    completionHandlers.first?()
    print(instance.x)
    // Prints "100"
    ```
  • 自动闭包

    自动闭包是一种自动创建的用来把作为实际参数传递给函数的表达式打包的闭包。

    自动闭包允许你延迟处理,因此闭包内部的代码直到你调用它的时候才会运行。
    ```
    var customersInLine = ["Chris", "Alex", "Ewa", "Barry", "Daniella"]
    print(customersInLine.count)
    // Prints "5"

    let customerProvider = { customersInLine.remove(at: 0) }
    print(customersInLine.count)
    // Prints "5"

    print("Now serving (customerProvider())!")
    // Prints "Now serving Chris!"
    print(customersInLine.count)
    // Prints "4"
    如果闭包永远不被调用,那么闭包里边的表达式就永远不会求值。
    var customersInLine = ["Chris", "Alex", "Ewa", "Barry", "Daniella"]
    print(customersInLine.count)
    // Prints "5"

    let customerProvider = { customersInLine.remove(at: 0) }
    print(customersInLine.count)
    // Prints "5"

    print("Now serving (customerProvider())!")
    // Prints "Now serving Chris!"
    print(customersInLine.count)
    // Prints "4"
    ```

    @autoclosure 标志标记它的形式参数使用了自动闭包。调用函数就像它接收了一个 String 实际参数而不是闭包,实际参数自动地转换为闭包。
    // customersInLine is ["Ewa", "Barry", "Daniella"] func serve(customer customerProvider: @autoclosure () -> String) { print("Now serving \(customerProvider())!") } serve(customer: customersInLine.remove(at: 0)) // Prints "Now serving Ewa!"

    自动闭包允许逃逸,就同时使用 @autoclosure 和 @escaping 标志。

    // customersInLine is ["Barry", "Daniella"]
    var customerProviders: [() -> String] = []
    func collectCustomerProviders(_ customerProvider: @autoclosure @escaping () -> String) {
        customerProviders.append(customerProvider)
    }
    collectCustomerProviders(customersInLine.remove(at: 0))
    collectCustomerProviders(customersInLine.remove(at: 0))
    
    print("Collected \(customerProviders.count) closures.")
    // Prints "Collected 2 closures."
    for customerProvider in customerProviders {
        print("Now serving \(customerProvider())!")
    }
    // Prints "Now serving Barry!"
    // Prints "Now serving Daniella!"

转载于:https://www.cnblogs.com/ccjoy/p/8687624.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值