swift 閉包
閉包(closures)是自包含的功能**塊,可以在**中使用或者用來作為引數傳值。
swift 中的閉包與 c 和 objective-c 中的**塊(blocks)以及其他一些程式語言中的 匿名函式比較相似。
全域性函式和巢狀函式其實就是特殊的閉包。
閉包的形式有:
全域性函式 巢狀函式 閉包表示式
有名字但不能捕獲任何值。 有名字,也能捕獲封閉函式內的值。 無名閉包,使用輕量級語法,可以根據上下文環境捕獲值。
swift中的閉包有很多優化的地方:
根據上下文推斷引數和返回值型別
從單行表示式閉包中隱式返回(也就是閉包體只有一行**,可以省略return)
可以使用簡化引數名,如$0, $1(從0開始,表示第i個引數...)
提供了尾隨閉包語法(trailing closure syntax)
語法
以下定義了乙個接收引數並返回指定型別的閉包語法:
例項 import cocoa
let studname =
studname()
以上程式執行輸出結果為:
swift 閉包例項。
以下閉包形式接收兩個引數並返回布林值:
例項 import cocoa
let divide =
let result = divide(200, 20)
print (result)
以上程式執行輸出結果為: 10
閉包表示式
閉包表示式是一種利用簡潔語法構建內聯閉包的方式。 閉包表示式提供了一些語法優化,使得撰寫閉包變得簡單明瞭。
sort 函式
swift 標準庫提供了名為sort的函式,會根據您提供的用於排序的閉包函式將已知型別陣列中的值進行排序。
排序完成後,sort(_:)方法會返回乙個與原陣列大小相同,包含同型別元素且元素已正確排序的新陣列,原陣列不會被sort(_:)方法修改。
sort(_:)方法需要傳入兩個引數:
已知型別的陣列
閉包函式,該閉包函式需要傳入與陣列元素型別相同的兩個值,並返回乙個布林型別值來表明當排序結束後傳入的第乙個引數排在第二個引數前面還是後面。如果第乙個引數值出現在第二個引數值前面,排序閉包函式需要返回true,反之返回false。 例項
import cocoa
let names = ["at", "ae", "d", "s", "be"]
// 使用普通函式(或內嵌函式)提供排序功能,閉包函式型別需為(string, string) -> bool。
import cocoa
let names = ["at", "ae", "d", "s", "be"]
// 使用普通函式(或內嵌函式)提供排序功能,閉包函式型別需為(string, string) -> bool。
func backwards(s1: string, s2: string) -> bool
var reversed = names.sorted(by: backwards)
print(reversed)
以上程式執行輸出結果為:
["s", "d", "be", "at", "ae"]
如果第乙個字串 (s1) 大於第二個字串 (s2),backwards函式返回true,表示在新的陣列中s1應該出現在s2前。 對於字串中的字元來說,"大於" 表示 "按照字母順序較晚出現"。 這意味著字母"b"大於字母"a",字串"s"大於字串"d"。 其將進行字母逆序排序,"at"將會排在"ae"之前。
引數名稱縮寫
swift 自動為內聯函式提供了引數名稱縮寫功能,您可以直接通過$0,$1,$2來順序呼叫閉包的引數。 例項
import cocoa
let names = ["at", "ae", "d", "s", "be"]
var reversed = names.sorted( by: )
print(reversed)
$0和$1表示閉包中第乙個和第二個string型別的引數。
以上程式執行輸出結果為:
["s", "d", "be", "at", "ae"]
如果你在閉包表示式中使用引數名稱縮寫, 您可以在閉包引數列表中省略對其定義, 並且對應引數名稱縮寫的型別會通過函式型別進行推斷。in 關鍵字同樣也可以被省略.
運算子函式
實際上還有一種更簡短的方式來撰寫上面例子中的閉包表示式。
swift 的string型別定義了關於大於號 (>) 的字串實現,其作為乙個函式接受兩個string型別的引數並返回bool型別的值。 而這正好與sort(_:)方法的第二個引數需要的函式型別相符合。 因此,您可以簡單地傳遞乙個大於號,swift可以自動推斷出您想使用大於號的字串函式實現:
import cocoa
let names = ["at", "ae", "d", "s", "be"]
var reversed = names.sorted(by: >)
print(reversed)
以上程式執行輸出結果為:
["s", "d", "be", "at", "ae"]
尾隨閉包
尾隨閉包是乙個書寫在函式括號之後的閉包表示式,函式支援將其作為最後乙個引數呼叫。
func somefunctionthattakesaclosure(closure: () -> void)
// 以下是不使用尾隨閉包進行函式呼叫
somefunctionthattakesaclosure()
// 以下是使用尾隨閉包進行函式呼叫
somefunctionthattakesaclosure() 例項
import cocoa
let names = ["at", "ae", "d", "s", "be"]
//尾隨閉包
var reversed = names.sorted()
print(reversed)
sort() 後的 為尾隨閉包。
以上程式執行輸出結果為:
["s", "d", "be", "at", "ae"]
注意: 如果函式只需要閉包表示式乙個引數,當您使用尾隨閉包時,您甚至可以把()省略掉。
reversed = names.sort
捕獲值
閉包可以在其定義的上下文中捕獲常量或變數。
即使定義這些常量和變數的原域已經不存在,閉包仍然可以在閉包函式體內引用和修改這些值。
swift最簡單的閉包形式是巢狀函式,也就是定義在其他函式的函式體內的函式。
巢狀函式可以捕獲其外部函式所有的引數以及定義的常量和變數。
看這個例子:
func makeincrementor(forincrement amount: int) -> () -> int
return incrementor }
乙個函式makeincrementor ,它有乙個int型的引數amout, 並且它有乙個外部引數名字forincremet,意味著你呼叫的時候,必須使用這個外部名字。返回值是乙個()-> int的函式。
函式題內,宣告了變數runningtotal 和乙個函式incrementor。
incrementor函式並沒有獲取任何引數,但是在函式體內訪問了runningtotal和amount變數。這是因為其通過捕獲在包含它的函式體內已經存在的runningtotal和amount變數而實現。
由於沒有修改amount變數,incrementor實際上捕獲並儲存了該變數的乙個副本,而該副本隨著incrementor一同被儲存。
所以我們呼叫這個函式時會累加:
import cocoa
func makeincrementor(forincrement amount: int) -> () -> int
return incrementor }
let incrementbyten = makeincrementor(forincrement: 10)
// 返回的值為10
print(incrementbyten())
// 返回的值為20
print(incrementbyten())
// 返回的值為30
print(incrementbyten())
以上程式執行輸出結果為: 10
20 30
閉包是引用型別
上面的例子中,incrementbyten是常量,但是這些常量指向的閉包仍然可以增加其捕獲的變數值。
這是因為函式和閉包都是引用型別。
無論您將函式/閉包賦值給乙個常量還是變數,您實際上都是將常量/變數的值設定為對應函式/閉包的引用。 上面的例子中,incrementbyten指向閉包的引用是乙個常量,而並非閉包內容本身。
這也意味著如果您將閉包賦值給了兩個不同的常量/變數,兩個值都會指向同乙個閉包:
import cocoa
func makeincrementor(forincrement amount: int) -> () -> int
return incrementor }
let incrementbyten = makeincrementor(forincrement: 10)
// 返回的值為10
incrementbyten()
// 返回的值為20
incrementbyten()
// 返回的值為30
incrementbyten()
// 返回的值為40
incrementbyten()
let alsoincrementbyten = incrementbyten
// 返回的值也為50
print(alsoincrementbyten())
以上程式執行輸出結果為: 50
16 Swift錯誤處理
錯誤處理是響應錯誤以及從錯誤中恢復的過程。swift提供了在執行對可恢復錯誤丟擲 捕獲 傳送和操作的高階支援 錯誤處理又稱之為異常處理 某些操作並不能總是保證執行所有 都可以執行或總會產生出有用的結果。可選型別用來表示值可能為空,但當執行失敗的時候,通常要去了解此次失敗是由什麼引起的,就可以做出與之...
Swift閉包2 尾閉包
假設有這樣乙個函式 這個函式的最後乙個引數是乙個閉包,並且,這個閉包表示式很長。如果按照正常的方式來呼叫這個函式的話,需要在引數裡指明這個函式的引數名,然後後面跟著乙個閉包表示式。比如下面這種函式 func somefunctionthattakesaclosure closure void 正常的...
Swift基礎 閉包
閉包是自包含的函式 塊,可以在在 中被傳遞和使用。閉包能捕獲和儲存騎在上下文中任意常量和變數的引用。這就是所謂的閉合幷包裹著這些常量和變數,俗稱閉包。swift會為我們管理在捕獲過程中設計的所有記憶體操作。閉包表示式式一種利用簡潔語法構建內聯的方式 2.1 sorted函式 swift標準庫提供了s...