閉包的主要意義是在一些場景中實現(xiàn)語法的優(yōu)化疯坤,比如可以利用上下文來推斷出參數(shù)和返回值的類型,而不需要像函數(shù)一樣必須指定相應(yīng)的參數(shù)類型和返回值類型靶剑,例如:在一些單獨的表達式中閉包可以省略return的關(guān)鍵字蜻拨,對于參數(shù)名也可以進行一定程度的簡寫,使得代碼更加緊湊桩引;
- 閉包的標準語寫法
var arr:[Int] = [1,3,5,7,9,2,4,6,8,0]
arr.sorted()
func compareTwoInoInts(a:Int,b:Int)->Bool{
return a>b
}
arr.sorted(by: compareTwoInoInts)
//閉包和匿名函數(shù)有點類似
arr.sorted(by: {(a:Int,b:Int)->Bool in
return a>b
})
var strArr = ["d","cd","bcd","abcd","abc","ab","a"]
strArr.sorted(by: {(s1:String,s2:String)->Bool in
if s1.characters.count != s2.characters.count{
return s1.characters.count < s2.characters.count
}
return s1 < s2
})
- 閉包的簡化寫法
//閉包的簡化式寫法
//1缎讼、如果閉包的邏輯很簡單,只有一句話時坑匠,可以不用換行寫
arr.sorted(by: {(a:Int,b:Int)->Bool in return a>b})
//2血崭、閉包具有根據(jù)上下文,根據(jù)當前的情況來推斷傳入的參數(shù)以及返回的參數(shù)的能力
arr.sorted(by: {a,b in return a>b})
//3笛辟、閉包中return這個關(guān)鍵字是可以省略的,面對比較復(fù)雜的情況還是不能省略的
arr.sorted(by: {a,b in a>b})
//4功氨、參數(shù)名也是可以省略的
arr.sorted(by: {$0 > $1})
arr.sorted(by: >)
- Trailing Closure 結(jié)尾閉包
針對比較復(fù)雜的閉包邏輯,如果這個閉包是放在最后手幢,在具體調(diào)用時可以將閉包寫在函數(shù)的后面捷凄,即:
strArr.sorted(){ (s1,s2) in
if s1.characters.count != s2.characters.count{
return s1.characters.count < s2.characters.count
}
return s1 < s2
}
- Capturing Values 數(shù)值捕獲
即閉包可以智能的去尋找在閉包的函數(shù)體中所使用的變量,如果發(fā)現(xiàn)它不是被傳入的變量围来,則會向外一層去找相應(yīng)的變量跺涤;
arr.sorted(){return fabs(Float($0 - 5)) < fabs(Float($1 - 5))}
//Capturing Values 數(shù)值捕獲
var num = 3
arr.sorted(){return fabs(Float($0 - num)) < fabs(Float($1 - num))}
- 值類型和引用類型
- 值類型 Value Type
所謂的值類型匈睁,是指當它作為參數(shù)傳入函數(shù)的時候,包括被賦值的時候所產(chǎn)生的是一個同類型的副本,例如:
var a:Int = 2
var b:Int = a
b //值為2
b+=1
b //3桶错,操作b不會改變a
a //2
a-=1
a //1,操作a也不會改變b
b //3
Swift中的值類型包括:Int航唆、Float、Double院刁、Bool糯钙、Tuple、String退腥、Array任岸、Dictionary
注意:在很多其他語言中Array、Dictionary會被包裝成類狡刘,是引用類型
- 引用類型 Reference Type
Swift中的引用類型:函數(shù)Function享潜,閉包Closure
//引用類型,例如:
//參數(shù):todayMiles嗅蔬,返回值:函數(shù)
func calcTotalMiles(todayMiles:Int) -> ()->Int{
var totalMiles = 0
//calcTotalMiles函數(shù)的返回值是個函數(shù)類型剑按,這個函數(shù)的具體值是用閉包實現(xiàn)的,并且用到了數(shù)值捕獲
return{ totalMiles += todayMiles; return totalMiles}
}
var dailyTwoMiles = calcTotalMiles(todayMiles: 2)
dailyTwoMiles() //2
dailyTwoMiles() //4
dailyTwoMiles() //6
var myPlan = dailyTwoMiles
myPlan() //8
dailyTwoMiles() //10