- Swift 4從零到精通iOS開發
- 張益琿
- 1388字
- 2019-12-09 14:31:25
5.3 理解閉包結構
閉包結構對于編程初學者來說可能會難于理解一些。在學習關于閉包的過程中,讀者首先應該理解閉包的結構與實質。
5.3.1 閉包的語法結構
使用Xcode開發工具創建一個命名為Closures的playground文件,本章將在其中進行代碼的演練。5.2節中向讀者介紹了有關函數的內容,函數的設計思路是將有一定功能的代碼塊包裝在一起,通過函數名實現復用。閉包和函數有著類似的作用,然而閉包的設計大多數情況下并不是為了代碼的復用,而是傳遞功能代碼塊和處理回調結構。首先,一個完整的函數包含函數名、參數列表、返回值和函數體,示例如下:

將上面函數的功能使用閉包來實現,代碼如下:

上面的代碼創建了一個名為myClosures的閉包常量,閉包在語法上有這樣的標準結構:{(參數列表)->返回值in閉包體}。首先閉包的最外層由大括號包圍,內部由閉包關鍵字in來進行分割,關鍵字in前面為閉包結構的參數列表和返回值,其書寫規則與函數一致,in關鍵字后面為閉包體,用于實現具體功能。上面示例的閉包和函數原理上完全相同,并且閉包也可以像函數一樣被調用,示例代碼如下:
//對函數進行調用 將返回9 myFunc(param: 3) //對閉包進行調用 將返回9 myClosures(3)
與函數不同的是,閉包的返回值是可以省略的,在閉包體中,如果有return返回,則閉包會自動將return的數據類型作為返回值類型,上面的閉包代碼也可以簡寫為如下樣式:

5.3.2 通過實現一個排序函數來深入理解閉包
在實踐中分析與解決問題是學習編程的一條捷徑。本節將帶領讀者通過分析問題、探討解決方案、進行初步實現、優化實現方式等一步步深入了解閉包的用法。學習這種分析解決問題的方式在編程中十分有益,其思路如圖5-1所示。

圖5-1 分析與解決問題思路
在實際開發中,開發者經常會遇到不同的排序需求,例如對商品價格排序、文章熱度排序、消息時間先后排序、學生成績排序等。很多情況下,開發者要排序的對象并不是簡單的數字類型值或者字符串類型值,而是自定義的復雜對象,也就是開發者常用的類。對于這種類型的排序需求,應該如何實現呢?首先應該明確需求問題:
(1)應該實現一個函數,來對數組類型排序。
(2)數組中的元素可以是任意的復雜類型。
實現根據復雜類型數據中的某一個屬性進行排序,例如學生的成績。
(1)針對上面提出的需求問題,設計初步的實現思路。
(2)以通用的數組類型作為函數的參數。
若要實現對自定義復雜類型的排序操作,需要將排序算法作為參數傳入函數。
編寫函數的結構示例如下:

提示
Any在Swift語言中代表任意類型。
mySort()函數中需要傳入兩個參數,一個是要進行排序的數組數據,另一個是一個閉包排序方法,這個閉包有兩個Int類型的參數,表示數組中兩個相鄰的元素。第1個參數表示前一個元素,第2個參數表示后一個元素,這個閉包有一個Bool類型的返回值,返回true則表示正向排序,即參數中的第1個元素和第2個元素不交換位置,返回false表示逆向排序,即參數中的第1個元素和第2個元素交換位置。之后,根據上面的分析來對mySort函數進行實現,代碼如下:

如上代碼所示,使用了冒泡排序算法來進行排序操作,而具體兩個元素的排序規則是由閉包sortClosure來實現的。swap()函數是Swift語言中的一個交換函數,用來實現數組元素的交換,由于需要對原數組數據進行操作,需要使用inout類型的數組參數。
先使用整型數組來對編寫的排序函數進行測試,代碼如下:

提示
as!的作用是類型轉換。
編寫一個自定義的類來進行排序測試,示例如下:

以上代碼模擬了一個學生類,每一個學生對象由名字和分數組成,閉包實現了對學生分數的排序規則。