/* 閉包(Closures)
* 閉包是自包含的功能代碼塊,可以在代碼中使用或者用來作為參數(shù)傳值。
* 在Swift中的閉包與C、OC中的blocks和其它編程語言(如Python)中的lambdas類似。
* 閉包可以捕獲和存儲上下文中定義的的任何常量和變量的引用。這就是所謂的變量和變量的自封閉,
* 因此命名為”閉包“("Closures)").Swift還會處理所有捕獲的引用的內(nèi)存管理。
*
* 全局函數(shù)和嵌套函數(shù)其實就是特殊的閉包。
* 閉包的形式有:
* (1)全局函數(shù)都是閉包,有名字但不能捕獲任何值。
* (2)嵌套函數(shù)都是閉包,且有名字,也能捕獲封閉函數(shù)內(nèi)的值。
* (3)閉包表達式都是無名閉包,使用輕量級語法,可以根據(jù)上下文環(huán)境捕獲值。
*
* Swift中的閉包有很多優(yōu)化的地方:
* (1)根據(jù)上下文推斷參數(shù)和返回值類型
* (2)從單行表達式閉包中隱式返回(也就是閉包體只有一行代碼,可以省略return)
* (3)可以使用簡化參數(shù)名,如$0, $1(從0開始,表示第i個參數(shù)...)
* (4)提供了尾隨閉包語法(Trailing closure syntax)
*/
// 下面用Swift標準庫中的sort方法來一步步簡化閉包寫法
// sort函數(shù)需要兩個參數(shù)
// 參數(shù)一:數(shù)組
// 參數(shù)二:一個閉包:帶有兩個參數(shù),這兩個參數(shù)類型與數(shù)組中的元素類型相同,返回值是Bool
var names = ["Swift", "Arial", "Soga", "Donary"]
// 第一種方式:使用函數(shù)
func backwards(firstString: String, secondString: String) -> Bool {
return firstString > secondString // 升序排序
}
// 這里第二個參數(shù),傳了一個函數(shù)
// reversed is equal to ["Swift", "Soga", "Donary", "Arial"]
var reversed = sort(nams, backwards)
// 第二種方式:使用閉包方式
// 完整閉包寫法是在花括號內(nèi)有參數(shù)列表和返回值,用關(guān)鍵字in表明閉包體的開始
// (firstString: String, secondString: String) 閉包參數(shù)列表
// -> Bool 指明閉包返回值類型是Bool
// in關(guān)鍵字表明閉包體的開始
reversed = sort(names, { (firstString: String, secondString: String) -> Bool in
return firstString > secondString
})
// 這里可以進一步簡化寫法,因為閉包代碼比較短,可以寫到一行上
reversed = sort(names, { (firstString: String, secondString: String) -> Bool in return firstString > secondString})
// 下面再進一步簡化寫法 :根據(jù)環(huán)境上下文自動推斷出類型
// 參數(shù)列表都沒有指明類型,也沒有指明返回值類型,這是因為swift可以根據(jù)上下文推測出
// firstString和secondString的類型會是names數(shù)組元素的類型,而返回值類型會根據(jù)return語句結(jié)果得到
reversed = sort(names, { firstString, secondString in return firstString > secondString})
// 再進一步簡化:隱式返回(單行語句閉包)
// 因為閉包體只有一行代碼,可以省略return
reversed = sort(names, { firstString, secondString in firstString > secondString})
// 再進一步簡化:使用簡化參數(shù)名($i,i=0,1,2...從0開始的)
// Swift會推斷出閉包需要兩個參數(shù),類型與names數(shù)組元素相同
reversed = sort(names, { $0 > $1 })
// 最簡單的一種寫法:使用操作符
reversed = sort(names, >)
/*
* 尾隨閉包(Trailing Closures)
* 如果函數(shù)需要一個閉包參數(shù)作為參數(shù),且這個參數(shù)是最后一個參數(shù),而這個閉包表達式又很長時,
* 使用尾隨閉包是很有用的。尾隨閉包可以放在函數(shù)參數(shù)列表外,也就是括號外。如果函數(shù)只有一個參數(shù),
* 那么可以把括號()省略掉,后面直接跟著閉包。
*/
// Array的方法map()就需要一個閉包作為參數(shù)
let strings = numbers.map { // map函數(shù)后面的()可以省略掉
(var number) -> String in
var output = ""
while number > 0 {
output = String(number % 10) + output
number /= 10
}
return output
}
/* 捕獲值
* 閉包可以根據(jù)環(huán)境上下文捕獲到定義的常量和變量。閉包可以引用和修改這些捕獲到的常量和變量,
* 就算在原來的范圍內(nèi)定義為常量或者變量已經(jīng)不再存在(很牛逼)。
* 在Swift中閉包的最簡單形式是嵌套函數(shù)。
*/
func increment(#amount: Int) -> (() -> Int) {
var total = 0
func incrementAmount() -> Int {
total += amount // total是外部函數(shù)體內(nèi)的變量,這里是可以捕獲到的
return total
}
return incrementAmount // 返回的是一個嵌套函數(shù)(閉包)
}
// 閉包是引用類型,所以incrementByTen聲明為常量也可以修改total
let incrementByTen = increment(amount: 10)
incrementByTen() // return 10,incrementByTen是一個閉包
// 這里是沒有改變對increment的引用,所以會保存之前的值
incrementByTen() // return 20
incrementByTen() // return 30
let incrementByOne = increment(amount: 1)
incrementByOne() // return 1
incrementByOne() // return 2
incrementByTen() // return 40
incrementByOne() // return 3
swift閉包
最后編輯于 :
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。
相關(guān)閱讀更多精彩內(nèi)容
- 閉包介紹 Swift閉包和Objective-C中的Block很類似,是一段自包含的函數(shù)代碼塊,可以在代碼中使用和...
- 本節(jié)知識點 閉包的基本概念 閉包基本使用 閉包表達式作為回調(diào)函數(shù) 閉包的多種寫法(尾隨閉包) 閉包表達式優(yōu)化 閉包...
- 一、閉包定義 一個擁有許多變量和綁定了這些變量的環(huán)境的表達式(通常是一個函數(shù)),因而這些變量也是該表達式的一部分。...
- https://github.com/codlife/SparkDeepDoc/blob/master/Spark...