與Objective-C相比,同是蘋果公司御用開發(fā)語言的Swift明顯在語法上要復(fù)雜很多,并且同一個(gè)語法功能的寫法也非常多,有時(shí)會帶來很多困惑。本文主要關(guān)注閉包的用法。Swift的閉包與在Objective-C 2.0的時(shí)候就引入的Block語法功能類似,都是一個(gè)能夠捕獲變量的可執(zhí)行實(shí)體。
實(shí)際使用中,Block的語法都中規(guī)中矩:
//定義閉包類型
typedef void (^BlockType)();
//創(chuàng)建閉包類型的變量
void (^blockVar)();
//創(chuàng)建閉包,簡化寫法
blockVar = ^{
NSLog(@"Block");
};
可以看出來,不管是定義閉包還是創(chuàng)建閉包,都是很規(guī)則的形式,用^開頭,包含參數(shù)列表、返回值類型等。
但作為Swift的重點(diǎn)語法閉包來說,就沒這么簡單了。它在不同場合可以有不同形式的簡寫,下面用示例來說明。
1. 完整形式
//定義閉包類型
typealias ClosureType = (Int, Int) -> Int
//定義閉包類型變量并創(chuàng)建閉包
var c1: ClosureType = {
(a: Int, b: Int) -> Int in
return a + b
}
//調(diào)用閉包
c1(1, 2)
完整的閉包包括參數(shù)列表和返回值類型,實(shí)現(xiàn)的時(shí)候全部放入{ }中,并且用in關(guān)鍵字隔開返回值類型和可執(zhí)行代碼。
2. 簡寫的閉包創(chuàng)建方式
Swift相比Objective-C擁有更加強(qiáng)大的推導(dǎo)能力,因此在類型已知的情況下,可以省略許多代碼。比如在閉包類型一定的情況下,可以省略返回值類型、參數(shù)列表等。
a. 省略返回值類型
//定義閉包類型
typealias ClosureType = (Int, Int) -> Int
//定義閉包類型變量并創(chuàng)建閉包
var c1: ClosureType = {
(a: Int, b: Int) in
return a + b
}
由于c1已經(jīng)確定擁有整型Int返回值,因此可以在實(shí)現(xiàn)閉包的時(shí)候不寫。
b. 省略參數(shù)類型
//定義閉包類型
typealias ClosureType = (Int, Int) -> Int
//定義閉包類型變量并創(chuàng)建閉包
var c1: ClosureType = {
(a, b) in
return a + b
}
實(shí)際上連參數(shù)列表的圓括號也是可以省略的:
//定義閉包類型變量并創(chuàng)建閉包
var c1: ClosureType = {
a, b in
return a + b
}
Swift還提供了位置參數(shù)的用法,可以用參數(shù)的位置來代替參數(shù)名稱:
//定義閉包類型變量并創(chuàng)建閉包
var c1: ClosureType = {
return $0 + $1
}
如果整個(gè)閉包中只有一個(gè)有計(jì)算結(jié)果的語句,并且它的類型與返回值類型相同,甚至可以省略return。
//定義閉包類型變量并創(chuàng)建閉包
var c1: ClosureType = {
$0 + $1
}
3. 作為函數(shù)參數(shù)的簡寫形式
閉包可以作為函數(shù)參數(shù),并且在作為函數(shù)的最后一個(gè)參數(shù)時(shí),能夠獲得額外的簡寫方式。
a. 完整形式
//定義閉包類型
typealias ClosureType = (Int, Int) -> Int
//定義使用閉包作為參數(shù)的函數(shù)
func compute(a: Int, b: Int, c: ClosureType) {
print(c(a, b))
}
//調(diào)用函數(shù)
compute(a: 1, b: 2, c: {
(a: Int, b: Int) -> Int in
return a * b
})
b. 簡單省略形式
//調(diào)用函數(shù)
compute(a: 1, b: 2, c: { $0 * $1 })
c. 作為最后一個(gè)參數(shù),可以不寫到圓括號中
//調(diào)用函數(shù)
compute(a: 1, b: 2) {
$0 * $1
}
d. 如果函數(shù)只有一個(gè)參數(shù),則連圓括號都可以省略
//定義使用閉包作為參數(shù)的函數(shù)
func compute(c: ClosureType) {
print(c(1, 2))
}
//調(diào)用函數(shù)
compute {
$0 * $1
}
這種形式在大量知名的開源框架中都有體現(xiàn),比如PromiseKit中的firstly、then、when等函數(shù)。
UIApplication.sharedApplication().networkActivityIndicatorVisible = true
firstly {
when(NSURLSession.GET("http://api.class.room/?method=provs").asArray())
}.then { (array) in
print(array)
}.always {
UIApplication.sharedApplication().networkActivityIndicatorVisible = false
}.error { (error) in
print(error)
}
4. 總結(jié)
合理使用Swift閉包的各種形式,結(jié)合函數(shù)的參數(shù)、返回值等,能夠讓代碼變得更加簡潔、表現(xiàn)力更強(qiáng),但同時(shí)會讓學(xué)習(xí)取消變得更加陡峭。