Swift特有語法:閉包

1. 閉包定義git

閉包:閉包是自包含的函數代碼塊,能夠在代碼中被傳遞和使用。閉包能夠捕獲和存儲其所在上下文中任意常量和變量的引用。 這就是所謂的閉合幷包裹着這些常量和變量,俗稱閉包。Swift 會管理在捕獲過程當中涉及到的全部內存操做。數組

閉包採起以下三種形式:安全

  • 全局函數是一個有名字但不會捕獲任何值的閉包
  • 嵌套函數是一個有名字並能夠捕獲其封閉函數域內值的閉包
  • 閉包表達式是一個利用輕量級語法所寫的能夠捕獲其上下文中變量或常量值的匿名閉包

2. sort函數閉包

sorted 函數(The Sorted Function):Swift 標準庫提供了sorted函數,會根據您提供的基於輸出類型排序的閉包函數將已知類型數組中的值進行排序。 一旦排序完成,函數會返回一個與原數組大小相同的新數組,該數組中包含已經正確排序的同類型元素。app

sorted函數須要傳入一個參數:函數

  • 閉包函數,該閉包函數須要傳入與數組類型相同的兩個值,並返回一個布爾類型值來告訴sorted函數當排序結束後傳入的第一個參數排在第二個參數前面仍是後面。若是第一個參數值出如今第二個參數值前面,排序閉包函數須要返回true,反之返回false

咱們經過sorted函數,使用閉包進行排序,代碼以下:優化

let names = ["Chris", "Alex", "Ewa", "Barry", "Daniella"]
        func backwards(s1 : String, s2 : String)->Bool{
            return  s1>s2
        }
        let reversed = names.sort(backwards)
        for item in reversed{
            print("item = : \(item)")
        }

3. 閉包表達式語法(Closure Expression Syntax)spa

閉包表達式語法有以下通常形式:code

{ (parameters) -> returnType in
    statements
}

優化了backwards函數對應的閉包表達式版本的代碼:blog

let reversed = names.sort({(s1 : String , s2 : String) -> Bool in return s1 > s2})

根據上下文推斷類型(Inferring Type From Context):實際上任何狀況下,經過內聯閉包表達式構造的閉包做爲參數傳遞給函數時,均可以推斷出閉包的參數和返回值類型,優化後代碼以下:

let reversed = names.sort({s1 , s2 in return s1 > s2})

參數名稱縮寫(Shorthand Argument Names):Swift 自動爲內聯函數提供了參數名稱縮寫功能,您能夠直接經過$0,$1,$2來順序調用閉包的參數。優化後代碼以下:

let reversed = names.sort({ $0 > $1 })

4. 尾隨閉包

尾隨閉包(Trailing Closures):若是須要將一個很長的閉包表達式做爲最後一個參數傳遞給函數,可使用尾隨閉包來加強函數的可讀性。 尾隨閉包是一個書寫在函數括號以後的閉包表達式,函數支持將其做爲最後一個參數調用。

下例介紹瞭如何在map方法中使用尾隨閉包將Int類型數組[16,58,510]轉換爲包含對應String類型的數組["OneSix", "FiveEight", "FiveOneZero"],代碼以下:

let digitNames = [0: "Zero", 1: "One", 2: "Two",   3: "Three", 4: "Four",
            5: "Five", 6: "Six", 7: "Seven", 8: "Eight", 9: "Nine"]
        let numbers = [16, 58, 510]
        let strings = numbers.map{
            (var number) -> String in
            var output = ""
            while number > 0 {
                output = digitNames[number % 10 ]! + output
                number /= 10
            }
            return output
        }
        
        for item in strings {
            print("item = \(item)")
        }

4.1 Swift中map

Map函數會遍歷集合類型並對其中的每個元素進行同一種的操做。Map的返回值是一個所得結果的數組。例如:咱們要對一個數組裏面的數據進行平方操做,常見的代碼以下:

let values: [Double]= [2.0,4.0,6.0,8.0]
var squares: [Double] = []
for value in values {
    squares.append(value * value)
}

上面的代碼中,咱們使用了常規的for in遍歷操做對其中的元素進行了平方操做,而後將計算的結果追加到一個變量數組裏面。雖然該部分的代碼很好的完成了要求,可是在Swift中咱們還有更簡潔和安全的代碼(上面的squaers是一個變量可能出現無心的數據修改)。下面來看看使用Map進行操做的代碼:

let values: [Double]= [2.0,4.0,6.0,8.0]
let squares: [Double] = values.map{$0 * $0}
//該段代碼不只更加簡潔並且squares是一個不可變的常量。

5. 捕獲值

捕獲值(Capturing Values):閉包能夠在其定義的上下文中捕獲常量或變量。 即便定義這些常量和變量的原域已經不存在,閉包仍然能夠在閉包函數體內引用和修改這些值。代碼以下:

func makeIncrementor(forIncrement amount : Int) -> () -> Int{
            var runningTotal = 0
            func incrementor() -> Int{
                runningTotal += amount
                return runningTotal
            }
            return incrementor
        }
        let incrementByTen = makeIncrementor( forIncrement: 10)
        let number = incrementByTen()
        print("incrementByTen = \(number)")

makeIncrementor返回類型爲() -> Int。 這意味着其返回的是一個函數,而不是一個簡單類型值。 該函數在每次調用時不接受參數只返回一個Int類型的值。 

相關文章
相關標籤/搜索