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!"
相關文章
相關標籤/搜索