閉包表達式語法
閉包表達式語法有如下的一般形式:
- 1
{ (parameters) -> (return type) in
statements
}
parameters--形式參數類型
type -- 返回值類型
statements -- 函數體
例如:
let bibao = {( num :Int , num1:Int) -> Int in
return num + num1
}
let get1 = bibao(20,30)
print("bibao de jieguo \(get1)")
輸出結果:bibao de jieguo 50
- 2
//模式2 用一行書寫
let bibao = {( num :Int , num1:Int) -> Int in return num + num1}
- 3
//模式3 省略 形式參數類型,只使用返回值類型
let bibao = {num , num1 -> Int in return num + num1
}
捕獲值
一個閉包能夠從上下文捕獲已被定義的常量和變量。即使定義這些常量和變量的原作用域已經不存在,閉包仍能夠在其函數體內引用和修改這些值。
func bibao2 (number num3:Int,number11 num4:Int) -> () -> Int{
var num5 = 4;
func add() -> Int{
num5 += num4;
num5+=num3
return num5
}
return add
}
let get2 = bibao2(number: 5,number11: 100)
print(get2())
輸出結果:109
分析:定義閉包bibao2,包含一個內嵌函數,可以捕獲上文的傳入參數num3,num4及內部定義變量num5, 返回add 作為一個閉包,bibao2的返回類型是() -> Int,說明返回的是一個函數,不需要任何形式參數,每次調用返回一個返回值為Int類型的函數,賦值給get2,最后調用get2(),即內部函數add(),得到函數調用的結果
如果打印三次:print(get2())
結果: 109 214 319
說明每次都捕獲了上下文常亮
如果這是個定義了get3;
let get3 = bibao2(number: 10,number11: 10)
print(get3())
輸出結果:24
說明新的閉包實例,回創建新的獨立的num5,閉包和實例之間建立一個強引用環
自動閉包
var customersInLine = ["Chris", "Alex", "Ewa", "Barry", "Daniella"]
print(customersInLine.count)
// Prints "5"
let customerProvider = { customersInLine.remove(at: 0) }
print(customersInLine.count)
// Prints "5"
print("Now serving \(customerProvider())!")
// Prints "Now serving Chris!"
print(customersInLine.count)
// Prints "4"
盡管 customersInLine 數組的第一個元素以閉包的一部分被移除了,但任務并沒有執行直到閉包被實際調用。
如果閉包永遠不被調用,那么閉包里邊的表達式就永遠不會求值。注意 customerProvider 的類型不是 String 而是 () -> String ——一個不接受實際參數并且返回一個字符串的函數
同理
當你傳一個閉包作為實際參數到函數的時候,你會得到與延遲處理相同的行為。
// customersInLine is ["Alex", "Ewa", "Barry", "Daniella"]
func serve(customer customerProvider: () -> String) {
print("Now serving \(customerProvider())!")
}
serve(customer: { customersInLine.remove(at: 0) } )
// Prints "Now serving Alex!"
傳遞一個形式參數為customer,類型為函數() 的函數{ customersInLine.remove(at: 0) }
作為實際參數給save函數,返回一個字符串