Swift閉包函數(shù)(Array)

閉包概述:(以下是我拷貝的)

閉包(Closures)

  • 閉包是自包含的功能代碼塊,可以在代碼中使用或者用來(lái)作為參數(shù)傳值。
  • 在Swift中的閉包與C、OC中的blocks和其它編程語(yǔ)言(如Python)中的lambdas類似。
  • 閉包可以捕獲和存儲(chǔ)上下文中定義的的任何常量和變量的引用。這就是所謂的變量和變量的自封閉,
  • 因此命名為”閉包“("Closures)").Swift還會(huì)處理所有捕獲的引用的內(nèi)存管理。
  • 全局函數(shù)和嵌套函數(shù)其實(shí)就是特殊的閉包。
  • 閉包的形式有:
  • (1)全局函數(shù)都是閉包,有名字但不能捕獲任何值。
  • (2)嵌套函數(shù)都是閉包,且有名字,也能捕獲封閉函數(shù)內(nèi)的值。
  • (3)閉包表達(dá)式都是無(wú)名閉包,使用輕量級(jí)語(yǔ)法,可以根據(jù)上下文環(huán)境捕獲值。
  • Swift中的閉包有很多優(yōu)化的地方:
  • (1)根據(jù)上下文推斷參數(shù)和返回值類型
  • (2)從單行表達(dá)式閉包中隱式返回(也就是閉包體只有一行代碼,可以省略return)
  • (3)可以使用簡(jiǎn)化參數(shù)名,如$0, $1(從0開始,表示第i個(gè)參數(shù)...)
  • (4)提供了尾隨閉包語(yǔ)法(Trailing closure syntax)

問題:對(duì)names中的元素按字母升序排序 (Z最小,A最大)

var names = ["Swift", "Arial", "Soga", "Donary"]

函數(shù)寫法

func backwards(s1: String, s2: String) -> Bool {
    return s1 > s2 // 升序排序
}

var reversed = names.sort(backwards)

把上面的普通函數(shù)寫法轉(zhuǎn)換為閉包函數(shù)

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

sort是一個(gè)排序函數(shù),它通過(guò)基于輸出類型排序的閉包函數(shù),給已知類型的數(shù)組數(shù)據(jù)的值排序。需要一個(gè)閉包參數(shù)作為參數(shù):Sort函數(shù)的完整抽象形態(tài)如下:

    names.sort { (String1, String2) -> Bool in
        do someting
        return Bool
    }

sort也是一個(gè)尾隨閉包函數(shù)(Trailing Closures)
如果函數(shù)需要一個(gè)閉包參數(shù)作為參數(shù),且這個(gè)參數(shù)是最后一個(gè)參數(shù),而這個(gè)閉包表達(dá)式又很長(zhǎng)時(shí),可以使用尾隨閉包。尾隨閉包可以放在函數(shù)參數(shù)列表外,也就是括號(hào)外。
如果尾隨閉包函數(shù)只有一個(gè)參數(shù),那么可以把括號(hào)()省略掉,后面直接跟著閉包。

尾隨閉包去掉括號(hào)

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

由于參數(shù)傳入時(shí)swift會(huì)進(jìn)行隱式類型推導(dǎo),省去參數(shù)類型

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

同理由于結(jié)果return時(shí)swift會(huì)進(jìn)行隱式類型推導(dǎo),省去返回值類型

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

既然類型都沒了,閉包里面自帶了一套默認(rèn)的參數(shù)名,你可以不聲明閉包參數(shù)列表。
第一參數(shù):$0,第二參數(shù):$1 ...
這是后閉包函數(shù)聲明中的參數(shù)列表和返回值類型都沒了
那么關(guān)鍵字in也省了吧,直接寫內(nèi)部結(jié)構(gòu)體

reversed = names.sort{
    return $0 > $1
}

如果內(nèi)部結(jié)構(gòu)體中只有return這么一句話,return也能省

reversed = names.sort{$0 > $1}

最簡(jiǎn)單的寫法,只留下操作符,注意,這時(shí)候尾閉包使用的是()
這種方法只適用于閉包中只有"默認(rèn)參數(shù)名"和"運(yùn)算符"這兩者的情況

reversed = names.sort(>)

閉包的運(yùn)用:捕獲值(內(nèi)嵌函數(shù)捕獲外部函數(shù)中定義的常量和變量)

func increment(amount amount: Int) -> (() -> Int) {
    var total = 0
    func incrementAmount() -> Int {
        total += amount // total是外部函數(shù)體內(nèi)的變量,這里是可以捕獲到的
        return total
    }
    return incrementAmount // 返回的是一個(gè)嵌套函數(shù)(閉包)
}

// 閉包是引用類型,所以incrementByTen聲明為常量也可以修改total
let incrementByTen = increment(amount: 10)
incrementByTen() // return 10,incrementByTen是一個(gè)閉包
incrementByTen() // return 20
incrementByTen() // return 30

let incrementByOne = increment(amount: 1)
incrementByOne() // return 1
incrementByOne() // return 2
incrementByOne() // return 3

//函數(shù)本身不占內(nèi)存,使用賦值后才占.
//所以多次調(diào)用同一個(gè)函數(shù)不會(huì)對(duì)其他調(diào)用該函數(shù)的變量造成影響
//incrementByTen和incrementByOne不會(huì)應(yīng)為他們都使用increment而相互影響
incrementByTen() // return 40
incrementByOne() // return 4
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

推薦閱讀更多精彩內(nèi)容

  • 閉包是自包含的函數(shù)代碼塊,可以在代碼中被傳遞和使用。Swift 中的閉包與 C 和 Objective-C 中的代...
    窮人家的孩紙閱讀 1,748評(píng)論 1 5
  • 閉包可以從定義它們的上下文中捕獲和存儲(chǔ)對(duì)任何常量和變量的引用。 這被稱為關(guān)閉這些常量和變量。 Swift處理所有的...
    Joker_King閱讀 598評(píng)論 0 2
  • 閉包是功能性自包含模塊,可以在代碼中被傳遞和使用。Swift中的閉包與 C 和 Objective-C中的 blo...
    AirZilong閱讀 353評(píng)論 0 2
  • 本章將會(huì)介紹 閉包表達(dá)式尾隨閉包值捕獲閉包是引用類型逃逸閉包自動(dòng)閉包枚舉語(yǔ)法使用Switch語(yǔ)句匹配枚舉值關(guān)聯(lián)值原...
    寒橋閱讀 1,574評(píng)論 0 3
  • 每個(gè)人心里都有一個(gè)遠(yuǎn)方,很早以前我們稱之為夢(mèng)想。而在夢(mèng)想越來(lái)越大眾化的今天,我們更愿意談?wù)勥h(yuǎn)方。關(guān)于青春,關(guān)于自由...
    李木子的七年閱讀 173評(píng)論 0 0