Swift 閉包
函數(shù) ()->()
Swift 中的閉包和 Objective-C 中的 block 類(lèi)似,閉包是功能性自包含模塊淮悼,可以在代碼中被傳遞和使用。 在 Swift 中 函數(shù)只是閉包的一種特殊形式洲愤。
1.全局函數(shù)是一個(gè)有名字但不會(huì)捕獲任何值的閉包
2.內(nèi)嵌函數(shù)是一個(gè)有名字可以捕獲到所在的函數(shù)域內(nèi)值的閉包
3.閉包表達(dá)式是一個(gè)沒(méi)有名字的可以捕獲上下文中的變量或者常量的閉包
定義函數(shù)
我們?cè)?Swift 中使用 func
關(guān)鍵字來(lái)定義函數(shù)颅痊,函數(shù)可以沒(méi)有參數(shù)和返回值,也可以有一個(gè)或者多個(gè)參數(shù)和返回值彻犁。在Swift中多個(gè)參數(shù)的返回值叫做元組(tuples
)
func foo(firstname:String ,lastname:String)->(fullname:String){
return("\(firstname) \(lastname)")
}
函數(shù)調(diào)用
let fullname = foo("zhao”,”sunny”)
函數(shù)類(lèi)型
每一個(gè)函數(shù)都有它的類(lèi)型叫胁,函數(shù)的類(lèi)型由函數(shù)本身的參數(shù)類(lèi)型和返回值類(lèi)型來(lái)決定的。
func sum(x:Int,y:Int) -> (result:Int){return x + Y}
上面這個(gè)函數(shù)的函數(shù)類(lèi)型就是
(Int,Int)->(Int)
函數(shù)類(lèi)型在構(gòu)建函數(shù)的時(shí)候當(dāng)成參數(shù)類(lèi)型或者返回值類(lèi)型來(lái)使用汞幢。
返回函數(shù)類(lèi)型
func foo()->((String,String) -> String){
func bar(firstname:String,lastname:String) ->(fullname:String){
return("\(firstname) \(lastname)")
}
return bar
}
let namecombination = foo()
namecombination("wang","er")
可變參數(shù)函數(shù)
可變參數(shù)函數(shù)是指函數(shù)可以接收不固定個(gè)參數(shù)驼鹅。在參數(shù)類(lèi)型后面添加 … 來(lái)標(biāo)記這個(gè)參數(shù)為可變參數(shù)。我們可以在函數(shù)中像訪問(wèn)數(shù)組一樣訪問(wèn)可變參數(shù)。
func foo(names:String...) ->() {
for name in names {
println("\(name)")
}
}
func foo("zhao","zhang","wang")
In-out 參數(shù)函數(shù)
傳入函數(shù)的參數(shù)值只能在函數(shù)域內(nèi)改變输钩。參數(shù)傳遞是值傳遞豺型,也就是說(shuō)我們?cè)诤瘮?shù)內(nèi)部修改了一個(gè)參數(shù)的值,在函數(shù)結(jié)束后买乃,函數(shù)外部訪問(wèn)到的參數(shù)值還是傳入函數(shù)之前的值触创,它并沒(méi)有隨著函數(shù)內(nèi)的修改而改變。在Objective-C 我們通過(guò)指針來(lái)保存函數(shù)內(nèi)修改過(guò)的值以供函數(shù)結(jié)束后外部訪問(wèn)为牍。常見(jiàn)的例子就是 NSError
的使用哼绑。
在Swift 中我們也可以做類(lèi)似的操作。我們需要inout
關(guān)鍵字來(lái)標(biāo)記要修改的參數(shù)碉咆。
func swapTwoInts(inout a: Int, inout b: Int) {
let temporaryA = a
a = b
b = temporaryA
}
var someInt = 3
var anotherInt = 107
swapTwoInts(&someInt, &anotherInt)
閉包 { ()->() in }
定義一個(gè)閉包
閉包是一個(gè)使用花括號(hào){}
包圍起來(lái)抖韩,并且使用函數(shù)類(lèi)型()->()
來(lái)定義的代碼模塊。->
符號(hào)分割了輸入?yún)?shù)和返回值類(lèi)型疫铜。在關(guān)鍵字 in
來(lái)區(qū)分閉包的頭和閉包函數(shù)體茂浮。
{(params) -> returnType in
statements
}
一個(gè)數(shù)組的map
閉包的例子
let names = ["zhao","wang","Li"]
names.map({
(name:String) -> String in
"\(name) has been map !"
})
已知參數(shù)類(lèi)型的閉包
map
的閉包是作為函數(shù)參數(shù)傳入的,所以 Swift 是可以做類(lèi)型推斷的壳咕,這樣的話(huà)我們就不需要在閉包中在描述閉包的函數(shù)類(lèi)型席揽,也就是我們可以省略 (String) -> (String)
部分,來(lái)簡(jiǎn)寫(xiě)閉包表達(dá)式
let names = ["zhao","wang","Li"]
names.map({
name in
"\(name) has been map !"
})
如果閉包有返回值我們也可以簡(jiǎn)寫(xiě)省略掉return
谓厘。
例如
let names = ["zhao","wang","Li"]
let orderNames = sort(names,{s1,s2 in s1 > s2})
閉包參數(shù)名簡(jiǎn)寫(xiě)
Swift 為內(nèi)聯(lián)函數(shù)提供了參數(shù)名稱(chēng)簡(jiǎn)寫(xiě)功能幌羞,您可以直接通過(guò) $0,$1,$2等名字來(lái)引用的閉包的參數(shù)的值。
let names = ["zhao","wang","Li"]
names.map({"\($0) has been map !"})
sort(names,{$0 > $1})
如果閉包是函數(shù)的最后一個(gè)參數(shù)竟稳,我們可以省略掉圓括號(hào)
names.map{"\($0) has been map !"}
sort(names){$0 > $1}
對(duì)于排序函數(shù) sort()
來(lái)說(shuō)作為參數(shù)的閉包表達(dá)式只進(jìn)行了兩個(gè)值的比較属桦,比較是通過(guò)操作符 >
來(lái)進(jìn)行的。在Swift中可以進(jìn)行操作符重載他爸,我們會(huì)發(fā)現(xiàn)在String
中定義了>
的函數(shù)實(shí)現(xiàn)聂宾,也就是 >
本身就是一個(gè)函數(shù) ,它接收兩個(gè)String
類(lèi)型的參數(shù) 并返回一個(gè)Bool
類(lèi)型的值诊笤。這和 Sort
函數(shù)的第二個(gè)參數(shù)的類(lèi)型是一致的系谐。所以,我們還可以進(jìn)一步簡(jiǎn)寫(xiě) Sort()
sort(names,>)
閉包跟函數(shù)是引用類(lèi)型
無(wú)論您將函數(shù)/閉包賦值給一個(gè)常量還是變量讨跟,您實(shí)際上都是將常量/變量的值設(shè)置為對(duì)應(yīng)函數(shù)/閉包的引用纪他。這也意味著如果您將閉包賦值給了兩個(gè)不同的常量/變量,兩個(gè)值都會(huì)指向同一個(gè)閉包.