標籤:工程師 div 匿名 cat column 括弧 內聯 spec lis
閉包(Closure)這個概念如果沒學過Swift的人應該也不會陌生。
學過Javascript的朋友應該知道,在Javascript中我們經常會討論閉包,很多前端工程師的面試題也會問到什麼是閉包。
那麼,什麼是閉包呢?
讓我們看下在Javascript中閉包的解釋:
Closures are functions that have access to variables from another function’s scope.
(This is often accomplished by creating a function inside a function. )
閉包是一個函數能夠訪問另外一個函數範圍內變數。
(這通常通過在一個函數內申明另一個函數來實現)
通過上面的定義我們不難判斷,閉包具備以下兩點特徵:
1. 閉包是函數
2. 閉包是函數內部的函數
3. 閉包可以訪問另一個函數的變數
我們先來看下Javascipt閉包的例子:
function createComparisonFunction(propertyName) { return function(object1, object2) { var value1 = object1[propertyName]; var value2 = object2[propertyName]; if (value1 < value2) { return -1; } else if (value1 > value2) { return 1; } else { return 0; } };}
測試代碼:
var compare = createComparisonFunction(“name”);var result = compare({ name: “Nicholas”, age: 35 }, { name: “Greg”, age: 28 });console.log(result); // 1
上面的Javascript代碼中我們可以看到,
createComparisonFunction函數內部申明的匿名函數可以訪問createComparisonFunction函數本身的參數,這正符合了我們閉包的定義。
好了,Swift中閉包大致也是類似的,我們來看下閉包在Swift中的定義:
Closures are discrete bundles of functionality that can be used in your application to accomplish specific tasks.
閉包是用來在你的應用程式內部完成某些特殊任務的一些彼此互不相關的函數集。
讀著有些拗口,還是讓我們用例子來說話吧,看下下面的例子:
我們先來看一個不適用閉包的數組排序的例子
import Cocoa// 不使用閉包var counts = [1, 6, 2, 28, 13, 2, 9, 100, 30]func sortAscending(i: Int, j: Int) -> Bool { return i < j}let sortedCounts = counts.sort(sortAscending)
現在,我們看下,使用閉包代碼會變得更加簡潔
import Cocoa// 使用閉包var counts = [1, 6, 2, 28, 13, 2, 9, 100, 30]let sortedCounts = counts.sort({ (i: Int, j: Int) -> Bool in return i < j})
Swift的閉包文法:
{(parameters) -> [return type] in
// Code
}
通過類型推斷(type inference)讓閉包變得更加簡潔:
import Cocoavar counts = [1, 6, 2, 28, 13, 2, 9, 100, 30]let sortedCounts = counts.sort({ i, j in i < j })
通過參數預留位置讓代碼變得更簡潔:
import Cocoavar counts = [1, 6, 2, 28, 13, 2, 9, 100, 30]let sortedCounts = counts.sort({ $0 < $1 })
不難判斷,上面的代碼$0代表了第一個參數也就是i, 而$1代表了第一個參數也就是j。
哇撒,代碼變得越來越短了嘛,還可以再短些嗎?
答案是可以的!
還記得C++的內聯函(inline function)數嘛,在swift中我們也有!
把括弧去掉就是了!
於是,代碼變成了如下的樣子:
import Cocoavar counts = [1, 6, 2, 28, 13, 2, 9, 100, 30]let sortedCounts = counts.sort { $0 < $1 }
Swift語言精要-閉包(Closure)