Swift4 闭包,例子代码

闭包

苹果官方文档 闭包

苹果官方文档翻译 闭包

  • 闭包表达式

    { (parameters) -> (return type) in
        statements
      }
    Sorted 方法

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

    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
    }

    若是闭包为函数惟一实参,并做为尾随闭包,能够省略括号git

    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 来明确闭包是容许逃逸的。swift

    var completionHandlers: [() -> Void] = []
    func someFunctionWithEscapingClosure(completionHandler: @escaping () -> Void) {
        completionHandlers.append(completionHandler)
    }

    闭包 @escaping 意味着你必须在闭包中显式地引用 selfapi

    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"

    若是闭包永远不被调用,那么闭包里边的表达式就永远不会求值。app

    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 实际参数而不是闭包,实际参数自动地转换为闭包。ide

    // 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!"
相关文章
相关标签/搜索