闭包表达式语法
闭包表达式语法有如下的一般形式:
- 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函数,返回一个字符串