importUIKit
varstr ="Hello, playground"
//復(fù)習(xí)函數(shù)
//練習(xí),寫(xiě)一個(gè)求平均數(shù)的函數(shù)
funcgetAverage (scores:[Int]) ->CGFloat{
varsum:CGFloat=0
forscinscores{
sum +=CGFloat(sc)
}
returnsum /CGFloat(scores.count)
}
getAverage([1,2,3,4,5])
/*
*
*1.函數(shù)可以帶有可變個(gè)數(shù)的參數(shù),這些參數(shù)在函數(shù)內(nèi)表現(xiàn)為數(shù)組的形式:這樣寫(xiě)也行
*/
funcsumOf(numbers:Int...) ->Int{
varsum =0;
foriteminnumbers{
sum += item
}
returnsum
}
sumOf(2,4,5,6)
//函數(shù)可以嵌套猜憎。被嵌套的函數(shù)可以訪問(wèn)外側(cè)函數(shù)的變量朴皆,你可以使用嵌套函數(shù)來(lái)重構(gòu)一個(gè)太長(zhǎng)或者太復(fù)雜的函數(shù)帕识。
funcsum(scores:Int...) ->Int{
varss =0;
foriteminscores{
ss += item
}
returnaverage(ss, scores.count)
}
funcaverage(number:Int, count:Int) ->Int{
returnnumber / count
}
varave =sum(1,2,3,4,5)
//函數(shù)是第一等類(lèi)型,這意味著函數(shù)可以作為另一個(gè)函數(shù)的返回值遂铡。上面的demo其實(shí)已經(jīng)證明了肮疗,average不就是第一個(gè)函數(shù)的返回值了么
funcmakeIncrementer() -> (Int->Int) {
funcaddOne(number:Int) ->Int{
return1+ number
}
returnaddOne
}
varincrement =makeIncrementer()
increment(7)
//函數(shù)也可以當(dāng)做參數(shù)傳入另一個(gè)函數(shù),這個(gè)是我最喜歡的,在OC里面經(jīng)常用的
//在下面這個(gè)函數(shù)的demo中扒接,其實(shí)是將第一個(gè)小函數(shù)當(dāng)做實(shí)參傳入到了第二個(gè)大函數(shù)中伪货,第二個(gè)大函數(shù)中存在一個(gè)參數(shù)類(lèi)型和返回類(lèi)型和小函數(shù)的形參來(lái)接收,實(shí)際上就是另外一個(gè)小函數(shù)钾怔,我是這樣理解的碱呼,個(gè)人習(xí)慣不一樣,只要能記得這個(gè)語(yǔ)法就好我覺(jué)得
funclessThan(number:Int) ->Bool{
returnnumber <10
}
funchasMatch(list:[Int],condition:Int->Bool) ->Bool{
foriteminlist{
ifcondition(item){
returntrue
}else{
returnfalse
}
}
returntrue
}
varnumbers = [20,9,12,7]
hasMatch(numbers,lessThan)
//再寫(xiě)一個(gè)玩玩//第一個(gè)函數(shù)不會(huì)計(jì)算平均數(shù)宗侦,得依靠傳過(guò)來(lái)的一個(gè)函數(shù)計(jì)算愚臀,這個(gè)函數(shù)會(huì)計(jì)算
funcMeGetAverage(items:[Int],myMethod:(Int,Int)->Int) ->Int{
varsum =0
foriteminitems{
sum += item
}
returnmyMethod(sum,items.count)
}
funcgetAverage(sum:Int,count:Int)->Int{
returnsum / count
}
varnumbers1 = [1,2,3,4,5]
MeGetAverage(numbers1,getAverage)
/**
*2.閉包
*函數(shù)實(shí)際上是一種特殊的閉包,你可以使用{}來(lái)創(chuàng)建一個(gè)匿名閉包矾利。使用in將參數(shù)和返回值類(lèi)型聲明與閉包函數(shù)體進(jìn)行分離姑裂。
*/
//具體沒(méi)咋看懂啊
//numbers.map({
//(number: Int) -> Int in
//let result = 3 * number
//return result
//})
//let mappedNumbers = numbers.map({ number in 3 * number })
//mappedNumbers
//關(guān)于閉包網(wǎng)上找到的好像是能講解的知識(shí)點(diǎn)
/**
*
閉包有三種形式:
1.全局函數(shù)是一個(gè)有名字但不會(huì)捕獲任何值的閉包。
2.嵌套函數(shù)是一個(gè)有名字并可以捕獲到其封閉函數(shù)域內(nèi)的值的閉包男旗。
3.閉包表達(dá)式是一個(gè)利用輕量級(jí)語(yǔ)法所寫(xiě)的舶斧,可以捕獲其上下文中變量或常量值的匿名閉包。
今天察皇,我們要討論的是第三種形式捧毛,尤其討論它是如何將繁復(fù)的、可讀性比較差的業(yè)務(wù)邏輯代碼壓縮成高可讀性、簡(jiǎn)明明了的形式呀忧。
大家還記得數(shù)組的map方法么师痕?它的參數(shù)就是一個(gè)閉包,它會(huì)將數(shù)組里的每一個(gè)元素放在閉包中進(jìn)行處理而账,然后返回一個(gè)新的數(shù)組胰坟,甚至是與原數(shù)組不同元素類(lèi)型的新數(shù)組。
*/
numbers.map({
(number:Int) ->Intin
letresult =3* number
returnresult
})
letmappedNumbers =numbers.map({ numberin3* number })
//練習(xí)重寫(xiě)閉包泞辐,對(duì)所有奇數(shù)返回0笔横。在if語(yǔ)句中,條件必須是一個(gè)布爾表達(dá)式
vararr1 =numbers
vararr2 =arr1.map({ (item:Int) ->Intin
ifitem %2!=1{//偶數(shù)
returnitem
}else{//奇數(shù)
return0
}
})
print(arr1)
print(arr2)
/**
*靠這個(gè)我好像懂得了閉包網(wǎng)頁(yè)地址:http://www.tuicool.com/articles/faYbmy
*用一個(gè)例子來(lái)說(shuō)明咐吼。今天我辦生日聚會(huì)吹缔,要迎接很多人,并且為每個(gè)人都準(zhǔn)備了一句歡迎詞锯茄。我們要怎么做呢厢塘?首先我們將迎接的人放進(jìn)一個(gè)數(shù)組名叫g(shù)uestList,然后用一個(gè)名叫g(shù)reetPeople的函數(shù)為每個(gè)人生成歡迎詞:
func greetPeople(person: String) -> String
{
return "Hello, \(person)!"
}
let guestList = ["Chris", "Jill", "Tim"]
let fullGreetings = guestList.map(greetPeople)
然后將greetPeople函數(shù)作為guestList數(shù)組的map函數(shù)的參數(shù)傳入肌幽,并返回一個(gè)新的數(shù)組fullGreetings晚碾,這個(gè)數(shù)組就包含了每個(gè)人的歡迎詞。
如果我們想展示一下每個(gè)人的歡迎詞喂急,我們甚至可以這樣寫(xiě):
fullGreetings.map(println)
這時(shí)也許有人要質(zhì)疑了格嘁,println函數(shù)不是沒(méi)有返回值么?那么map函數(shù)會(huì)返回什么呢廊移?其實(shí)每一個(gè)沒(méi)有返回值的函數(shù)糕簿,都會(huì)返回一個(gè)空的元組(tuple),所以說(shuō)上述代碼的返回值其實(shí)是Array<()>狡孔。
上面的例子中我們就是將一個(gè)全局函數(shù)greetPeople作為一個(gè)閉包來(lái)使用的懂诗。
簡(jiǎn)明扼要的閉包表達(dá)式
其實(shí)Swift已經(jīng)為我們提供了很多簡(jiǎn)化的語(yǔ)法,可以讓我們保證代碼的高可讀性和維護(hù)性步氏。還用上面的例子來(lái)說(shuō)明响禽,對(duì)于greetPeople這個(gè)全局函數(shù)來(lái)說(shuō),其實(shí)只需要使用一次荚醒,所以我們沒(méi)必要單獨(dú)定義這個(gè)函數(shù)芋类。我們可以直接使用閉包表達(dá)式來(lái)處理:
let fullGreetings = guestList.map({(person: String) -> String in return "Hello, \(person)!"})
閉包表達(dá)式其實(shí)是函數(shù)的字面值,官方一般稱(chēng)之為匿名函數(shù)界阁。一般當(dāng)我們需要使用函數(shù)快速的實(shí)現(xiàn)一個(gè)簡(jiǎn)短的處理邏輯并且只使用一次的時(shí)候侯繁,我們可以省去函數(shù)名,使用簡(jiǎn)化的語(yǔ)法泡躯。上面的代碼中可以看到關(guān)鍵字in之前是閉包表達(dá)式的參數(shù)和返回值贮竟,in之后是閉包表達(dá)式實(shí)際處理邏輯的代碼區(qū)域丽焊。
下面我們將使用Swift更多的特性來(lái)進(jìn)一步簡(jiǎn)化閉包表達(dá)式。
我們知道Swift中有類(lèi)型推斷的特性咕别,所以我們可以取掉參數(shù)類(lèi)型:
let fullGreetings = guestList.map({(person) -> String in return "Hello, \(person)!" })
像我們示例中的這種單一閉包表達(dá)式技健,編譯器可以根據(jù)in之前的返回值類(lèi)型和return之后的返回?cái)?shù)據(jù)類(lèi)型自動(dòng)判斷,所以我們可以省略返回值和return關(guān)鍵字:
let fullGreetings = guestList.map({person in "Hello, \(person)!" })
其實(shí)在Swift中還提供了參數(shù)的簡(jiǎn)寫(xiě)方式:$0代表第一個(gè)參數(shù)惰拱、$1代表第二個(gè)參數(shù)以此類(lèi)推雌贱。所以我們又可以將參數(shù)名稱(chēng)省略:
let fullGreetings = guestList.map({ "Hello, \($0)!" })
當(dāng)函數(shù)的最后一個(gè)參數(shù)是閉包時(shí),可以將閉包寫(xiě)在()之外偿短,這也是Swift的一個(gè)特性欣孤,所以我們還可以繼續(xù)簡(jiǎn)化:
let fullGreetings = guestList.map(){ "Hello, \($0)!" }
當(dāng)函數(shù)有且僅有一個(gè)參數(shù),并該參數(shù)是閉包時(shí)昔逗,不但可以將閉包寫(xiě)在()外降传,還可以省略():
let fullGreetings = guestList.map{ "Hello, \($0)!" }
到目前為止,示例中的閉包表達(dá)式已經(jīng)被我們根據(jù)Swift的特性勾怒,簡(jiǎn)化為簡(jiǎn)明扼要婆排、高可讀性的閉包表達(dá)式了,是不是很酷呢控硼!
參考原文:Closure Expressions in Swift
*/