swift閉包(上) - 基本語法介紹

swift中的閉包是一個函數(shù)代碼塊捏雌,可以被傳遞和引用僧家;跟OC中的Block很相似拌倍,
閉包的定義:

{
  (形參類表) -> (返回值)in
  函數(shù)體
}

代碼:

{
  (num1: Int, num2: Int) -> Int in
  return num1 + num2
}

兩個參數(shù) 返回值為兩個參數(shù)之和的一個閉包;

我們定義一個閉包變量:

var closures: (_ age: Int, _ height: Int) -> Int
// 也可以不帶參數(shù)標簽
var closure1: (Int, Int) -> Int

拿個官方的例子簡單使用一下閉包涯穷,看下面代碼:

var nameArray = ["jack", "rose", "john"]
// 實用sort函數(shù)對數(shù)組進行排序
// nameArray.sort(by: <(String, String) throws -> Bool>)
// 可以看出sort函數(shù)需要的是一個 兩個String參數(shù)棍掐,返回值是bool的閉包
// 我們創(chuàng)建一個這樣的閉包,傳入進去拷况,如下
let sortClosure = {
  (s1: String, s2: String) -> Bool in
  // 放在sort函數(shù)中的含義就是作煌,哪個值小,誰就在前面
  return s1 < s2
}
nameArray.sort(by: sortClosure)

// result: jack赚瘦、john粟誓、rose
for i in nameArray {
  print(i)
}

當然官方還接介紹了其他的寫法,例如:

// 跟這句完全等價:nameArray.sort(by: sortClosure)
nameArray.sort(by: <)

我們這里就不多做贅述起意,就是一些簡寫的方法鹰服,開發(fā)中不常用,因為可讀性太差杜恰,了解即可

尾隨閉包

這個也是closures的簡寫获诈,這個寫法在實際開發(fā)中使用頻繁

// 定義了一個參數(shù)為閉包類型的函數(shù)
func testClosures(closers: (_ age: Int)-> Void) { }
// 調(diào)用該函數(shù)
// 寫法1. 完整的寫法:
testClosures(closers: {
   (age: Int) -> Void in
   print(age)
})
// 寫法2. 為了提高代碼的可讀性仍源,也可以這樣寫
// 區(qū)別:參數(shù)標簽可以省略,括號提前結(jié)束
testClosures() {
   (age: Int) -> Void in
   print(age)
}

使用尾隨閉包的條件:closures作為函數(shù)體的最后一個參數(shù)
針對上面例子舔涎,如果函數(shù)只有一個參數(shù)笼踩,且為閉包作為參數(shù)的話,還可以把括號省略

// 寫法3
testClosures { (age) in
}

在日常開發(fā)中亡嫌,經(jīng)常使用嚎于,例如網(wǎng)絡請求基本都是這種寫法
//多個參數(shù)也一樣,只是沒有了寫法3

// 函數(shù)定義
func testClosures(age: Int , closers: (_ age: Int)-> Void) { }
// 調(diào)用
testClosures(age: 10) { (age) in

}

逃逸閉包

當一個閉包作為參數(shù)傳到一個函數(shù)中挟冠,但是這個閉包在函數(shù)返回之后才被執(zhí)行于购,我們稱該閉包從函數(shù)中逃逸
這是官方翻譯,還是直接看代碼比較好理解

var complations: [() -> Void] = []
    
func someFunctions(param: ()-> Void) {
  complations.append(param)
}

這段代碼是編譯不過的知染,因為最后一個閉包參數(shù)肋僧,是在是在函數(shù)執(zhí)行完成之后,才可能會被執(zhí)行控淡,這種情況要加上關鍵字@escaping去修飾這個閉包參數(shù)嫌吠,代表這個閉包可能要在函數(shù)結(jié)束后,才會執(zhí)行這個閉包

var complations: [() -> Void] = []
    
func someFunctions(param: @escaping ()-> Void) {
  complations.append(param)
}

這樣就可以正常使用掺炭,逃逸閉包網(wǎng)絡請求中經(jīng)常遇到

自動閉包

在實際開發(fā)中使用不多辫诅,了解這種寫法。能看懂這種寫法即可
先看個例子:

let resultClo = { 2+3 }
// 完整寫法:
/*
{ () -> Int in
   return 2 + 3
}
*/

resultClo這就是一個自動閉包
自動閉包格式固定只支持:() -> T 這種格式的閉包
為什么要這樣寫涧狮,直接寫上表達式let resultClo = 2+3不更簡單嗎炕矮?
自動閉包可以延遲求值,需要的時候在取調(diào)用閉包resultClo()者冤,得到表達式的值
@autoclosure
這個關鍵字會自動將一個表達式轉(zhuǎn)換成閉包:

func serve(customer customerPrivoder: @autoclosure () -> String) {
  print(customerPrivoder())
}
// 調(diào)用
serve(customer: "jack")

使用了 @autoclosure 修飾函數(shù)參數(shù)肤视,在調(diào)用的時候只需要傳入一個String就行,因為他會把 "jack" => {"jack"}

tips:如果自己在實際開發(fā)中使用了 @autoclosure 最好明確寫明注釋涉枫,這個閉包會被延遲調(diào)用
蘋果官方的一些使用自動閉包的地方:
我們常用的斷言函數(shù)就使用了自動閉包钢颂,看下他的定義:

public func assert(_ condition: @autoclosure () -> Bool, _ message: @autoclosure () -> String = String(), file: StaticString = #file, line: UInt = #line)

函數(shù)接受自動閉包作為它的 condition 參數(shù)和 message 參數(shù);它的 condition 參數(shù)僅會在 debug 模式下被求值拜银,它的 message 參數(shù)僅當 condition 參數(shù)為 false 時被計算求值。

空和運算符 ?? 也是使用了@autoclosure技術(shù)

閉包的基本語法就梳理完成了遭垛,下篇會寫一下閉包的內(nèi)存管理和捕獲等相關知識點

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末尼桶,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子锯仪,更是在濱河造成了極大的恐慌泵督,老刑警劉巖,帶你破解...
    沈念sama閱讀 210,978評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件庶喜,死亡現(xiàn)場離奇詭異小腊,居然都是意外死亡救鲤,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 89,954評論 2 384
  • 文/潘曉璐 我一進店門秩冈,熙熙樓的掌柜王于貴愁眉苦臉地迎上來本缠,“玉大人,你說我怎么就攤上這事入问〉で拢” “怎么了?”我有些...
    開封第一講書人閱讀 156,623評論 0 345
  • 文/不壞的土叔 我叫張陵芬失,是天一觀的道長楣黍。 經(jīng)常有香客問我,道長棱烂,這世上最難降的妖魔是什么租漂? 我笑而不...
    開封第一講書人閱讀 56,324評論 1 282
  • 正文 為了忘掉前任,我火速辦了婚禮颊糜,結(jié)果婚禮上哩治,老公的妹妹穿的比我還像新娘。我一直安慰自己芭析,他們只是感情好锚扎,可當我...
    茶點故事閱讀 65,390評論 5 384
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著馁启,像睡著了一般驾孔。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上惯疙,一...
    開封第一講書人閱讀 49,741評論 1 289
  • 那天翠勉,我揣著相機與錄音,去河邊找鬼霉颠。 笑死对碌,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的蒿偎。 我是一名探鬼主播朽们,決...
    沈念sama閱讀 38,892評論 3 405
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼诉位!你這毒婦竟也來了骑脱?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,655評論 0 266
  • 序言:老撾萬榮一對情侶失蹤苍糠,失蹤者是張志新(化名)和其女友劉穎叁丧,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,104評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡拥娄,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,451評論 2 325
  • 正文 我和宋清朗相戀三年蚊锹,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片稚瘾。...
    茶點故事閱讀 38,569評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡牡昆,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出孟抗,到底是詐尸還是另有隱情迁杨,我是刑警寧澤,帶...
    沈念sama閱讀 34,254評論 4 328
  • 正文 年R本政府宣布凄硼,位于F島的核電站铅协,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏摊沉。R本人自食惡果不足惜锦亦,卻給世界環(huán)境...
    茶點故事閱讀 39,834評論 3 312
  • 文/蒙蒙 一筑凫、第九天 我趴在偏房一處隱蔽的房頂上張望查辩。 院中可真熱鬧与斤,春花似錦、人聲如沸尼斧。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,725評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽棺棵。三九已至楼咳,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間烛恤,已是汗流浹背母怜。 一陣腳步聲響...
    開封第一講書人閱讀 31,950評論 1 264
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留缚柏,地道東北人苹熏。 一個月前我還...
    沈念sama閱讀 46,260評論 2 360
  • 正文 我出身青樓,卻偏偏與公主長得像币喧,于是被迫代替她去往敵國和親轨域。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 43,446評論 2 348