Swift 中的闭包
- 上一篇中介绍了全局函数和嵌套函数
他们就是特殊的闭包。闭包就是一个功能性自包含模块,可以在代码中被当做参数传递或者直接使用,类似于Objective-C 中的Block
或者其他语言中的匿名函数
闭包的概念和定义
- 闭包的表达式语法一般形式为
{
(参数名1 : 参数类型,参数名2 : 参数类型)-> 返回值类型 in
闭包函数体
return 返回值
}
代码示例
let sumFunc = {
(x : Int , y : Int) -> Int in
return x + y
}
sumFunc(10,20)
- 如果闭包没有参数和返回值,那么基本参数列表、返回值、in 都可以省略 这就是最简单的闭包 代码示例
let simpleFunc = {
print("最简单的闭包")
}
simpleFunc()
使用尾随闭包
- 在Swift 开发中 尾随闭包是一个书写在函数括号之后的闭包表达式,韩式支持将其作为最后一个参数调用
- 代码示例
func calculate (opr : String, funN:(Int,Int) -> Int) {
switch opr {
case "+":
funN(10,5)
default:
funN(10,5)
}
}
calculate(opr: "+", funN: {(a:Int,b:Int) -> Int in return a+b })
//尾随闭包写法
calculate(opr: "-"){(a:Int,b:Int) -> Int in return a-b}
注意
- 将小括号提前到闭包表达式前面,闭包表达式位于括号的后面,这种形式就是尾随闭包
- 要使用尾随闭包,则闭包必须是参数列表的最后一个参数,如果不是最后一个的话,是无法使用尾随闭包的写法的
使用闭包表达式
- 根据上下文推断类型
类型推断是Swift 的强项 Swift 可以根据上下文环境推断出参数的类型和返回值的类型
定义一个标准的闭包
{
(a: Int , b : Int) -> Int in
return a + b
}
如果Swift 能推断出参数 a,b 都是Int 类型 返回值也是Int 类型 上面的代码可以简写为
{a , b in return a + b}
- 单行闭包表达式可以省略 return 关键字
代码示例
func calculate1(opr : String)->(Int,Int)->Int {
var result : (Int,Int)->Int
switch opr {
case "+":
//上下文推断类型
result = {a,b in return a+b}
case "-":
//省略return
result = {a,b in a-b}
default:
result = {a,b in return a-b}
}
return result
}
let f3:(Int,Int)->Int = calculate1(opr: "+")
print("\(f3(10,5))")
let f4:(Int,Int)->Int = calculate1(opr: "-")
print("\(f4(10,5))")
- 参数名称缩写
Swift 中提供参数名称缩写功能 用$0、$1、$2
来代表调用闭包中的参数$0
代表第一个参数$1
代表第二个参数 以此类推
func calculate2(opr : String)->(Int,Int)->Int {
var result : (Int,Int)->Int
switch opr {
case "+":
result = {$0 + $1}
case "-":
result = {$0 - $1}
default:
result = {$0 + $1}
}
return result
}
let f5:(Int,Int)->Int = calculate2(opr: "+")
print("\(f5(10,5))")
- 使用闭包返回值
let sub : Int = {(a : Int, b : Int) -> Int in return a-b}(10,5)
print("\(sub)")
闭包的捕获
- 嵌套函数或者闭包可以在其定义的上下文中捕获常量或者变量,即使定义的这些常量或者变量的原作用域已经不存在,仍然可以在闭包函数体内引用和修改这些常量或变量,这种机制称为捕获
- 代码示例
func makeArray()->(String)->[String] {
var array:[String] = [String]()
func addElement(element : String) -> [String] {
array.append(element)
return array
}
return addElement
}
var arr = makeArray()
print(arr("张三"))
print(arr("李四"))
let arr1 = arr("王二")
print(arr1)
输出