一、關于閉包
Swift函數是一等公民,Swift一大特性就是使用簡潔的語言去替代復雜的函數操作。
所謂閉包就是自包含的函數代碼塊,可以在代碼中被傳遞和使用。
Swift中的閉包與C、OC中的blcok和其他語言中的匿名函數相似。
"閉包可以捕獲和存儲其所在上下文中任意常量和變量的引用。被稱為包裹常量和變量。 Swift 會為你管理在捕獲過程中涉及到的所有內存操作。”
--------------------------------------摘錄來自: “The Swift Programming Language 中文版”。
閉包采取如下三種形式之一:
- 全局函數是一個有名字但不會捕獲任何值的閉包
- 嵌套函數是一個有名字并可以捕獲其封閉函數域內值的閉包
- 閉包表達式是一個利用輕量級語法所寫的可以捕獲其上下文中變量或常量值的匿名閉包
Swift 的閉包表達式擁有簡潔的風格,并鼓勵在常見場景中進行語法優化,主要優化如下:
- 利用上下文推斷參數和返回值類型
- 隱式返回單表達式閉包,即單表達式閉包可以省略 return 關鍵字
- 參數名稱縮寫
- 尾隨閉包語法”
從繁到簡看Swif中的閉包形式
//求兩個整數之和
func addFun(a:Int , b:Int) -> Int{
return a + b
}
//求兩個整數之積
func mulFun(a:Int , b:Int) -> Int{
return a * b
}
//對兩個數進行運算 為了動態計算我們傳入規則
func caculateFun(a:Int , b:Int , someFun:(Int,Int) ->Int) -> Int{
return someFun(a,b)
}
//之前我們通常會這樣做:
caculateFun(a: 10, b: 2, someFun: addFun) // 12
caculateFun(a: 10, b: 2, someFun: mulFun) // 20
//然后我們可以優化成這樣:
caculateFun(a: 20, b: 2, someFun: { (x, y) -> Int in
return x * y
})
//在Swift中我們可以繼續我們成更改形式
//我們稱之為 尾隨閉包
caculateFun(a: 20, b: 2) { (x, y) -> Int in
return x * y
}//40
//又因為Swift中存在類型推斷 能從caculateFun的聲明中推斷出傳入作為參數的函數期望接收兩個Int并返回一個Int值 所以我們繼續簡化
caculateFun(a: 10, b: 2) { (x, y) in
return x * y
} //20
//最后我們還可以忽略指定參數名,使用默認參數名$0(如果函數接收多個參數,使用$K作為第K-1個參數,如$0,$1,$2......)
caculateFun(a: 10, b: 40){
$0 * $1
}
//所以我們的例子在Swift中的閉包最簡形式就變成
caculateFun(a: 10, b: 40){ $0 * $1}
二、高階函數
接下來我們再看下高階函數Map,Filter,Reduce的使用,可以極大的簡化我們的代碼
Map
map用于將每個數組元素通過某個方法進行轉換。
//有一個數組 我們想對每一個數組中的元素都+1
let array = [1,2,3,4,5,6]
//之前我們一般創建一個空數組 遍歷源數組進行操作
var resultArray = [Int]()
for x in array {
resultArray.append(x + 1)
}
//現在我們一行搞定
resultArray = array.map{$0 + 1}
Filter
filter用于選擇數組元素中滿足某種條件的元素。
//我們要篩選大于零的
let numbers = [2, -5, 9, 7, -2, 5, 3, 1, 0, -3, 8]
//傳統
var result = [Int]()
for x in numbers {
result.append(x + 1)
}
//使用Filter
result = numbers.filter{$0 > 0}
Reduce
reduce方法把數組元素組合計算為一個值。
//我們要求和
let numbers = [2, -5, 9, 7, -2, 5, 3, 1, 0, -3, 8]
//傳統
var result = 0
for x in numbers {
result += x
}
//使用reduce
result = numbers.reduce(0,{$0+$1})