Swift闭包_7
闭包是自包含的函数代码块,可以在代码中被传递和使用,swift
中闭包与c
和oc
的代码块匿名函数比较相似
闭包可以捕获和储存其所在的上下文中的任意变量和常量的引用,被称之为包裹常量和变量,Swift
会为你管理在捕获过程中涉及到的所有内存操作
在上个章节介绍的全局和嵌套函数实际上也是特殊的闭包,闭包采取如下三种形式之一
- 全局函数是一个有名字但不会捕获任何值的闭包
- 嵌套函数是一个有名字并可以捕获其封闭函数域值的闭包
- 闭包表达式是利用一个轻量级语法所写的可以捕获其上下文变量或者常量值的匿名闭包
常闭包基本表达式
//最简单的闭包,无参数无返回值
/*
如果没有参数,没有返回值,可以
*/
let b1 = {
print("最简单的闭包")
}
b1()
//带参数的闭包,无返回值
/*
闭包中,参数,返回值,实现代码都写在{}中
需要使用一个关键字'in' 分隔定义和实现
{形参列表 -> 返回值类型 in //实现代码}
如果没有参数,没有返回值,可以省略,连 ‘in’都可以省略
*/
let b2 = { (x : Int , y : Int) in
print("带参数的闭包 参数x:\(x) y:\(y)")
}
b2(100, 200)//先打出b2 再打出’(‘ 就会有提示的
//带参数,带返回的闭包
let b3 = {(x : Int , y : Int) -> Int in
return x + y
}
print(b3(150, 150))
闭包表达式语法有如下的一般形式
{(parameters) -> returnType in
statements
}
闭包的函数体部分有关键字in
引入,该关键字表示闭包的参数与返回值类型已经定义完成,闭包函数体即将开始
soret方法
swift
标准库提供了名为sorted(by:)
的方法,它会根据你所提供的用于排序的闭包函数将已知类型的数组中的值进行排序,一旦排序完成,sorted(by:)
方法会返回一个与原数组大小相同,包含同类型且元素已正确排序的新数组,原数组不会被sorted(by:)
方法
let names = ["Chris","Alex","Ewar","Barry", "Daniella"]
//let sortedNames2 = names.sorted(by: { (s1: String, s2: String) -> Bool in return s1 > s2 } )
let sortedNames = names.sorted { (str1, str2) -> Bool in
return str1 > str2
}
print("排序后的数组\(sortedNames)")
//result:排序后的数组["Ewar", "Daniella", "Chris", "Barry", "Alex"]
根据上下文推断类型
因为排序闭包函数作为sorted(by:)
方法的参数传入的,swift
可以推断其参数与返回值的类型,sorted(by:)
方法被一个字符串数组调用,因此其参数必须是(String ,String) -> bool
类型的函数,这意味着(String,String)
和bool
并不需要作为闭包表达式定义的一部分,因为所有的类型都可以被正确推断,返回箭头->
和围绕在参数周围的括号也可以被省略
单表达式闭包隐式返回
单行表达式闭包可以通过省略return
let sortedNames3 = names.sorted { (str1, str2) -> Bool in str1 > str2}
参数名称所写
swift
自动为内联闭包提供了参数名称所写功能,你可以直接通过$0
,$1``$2
来顺序调用闭包的参数,以此类推
如果你在闭包表达式中使用参数名称所写,你可以在闭包定义中省略参数列表,并且对应参数名称所写的类型会通过函数的类型推断,in
关键字也可以同样被省略,因为此时闭包表达式完全由闭包函数体构成
let sortedNames4 = names.sorted { $0>$1 }
尾随闭包
如果你需要将一个很长的闭包表达式作为最后一个参数传递给函数,可以使用尾随闭包来增强函数的可读性,
如果函数的最后一个参数是闭包,函数参数可以提前结束,最后一个参数直接使用{}
包装闭包的代码
//函数
func endClosure(closure:()->Void) -> Void {
print("尾随闭包");
closure()
}
// 调用
//使用尾随闭包
endClosure {
print("尾随闭包2")
}
//不使用尾随闭包
endClosure(closure:{
print("尾随闭包3")
} )
值捕获
闭包可以在其定义的上下文中捕获常量或变量,即使定义这些常量和变量的员作用域已经不存在,闭包仍然可以在闭包函数体内引用和修改这些值
swift
中,可以捕获值的闭包的最简单形式就是嵌套函数,也就是定义在其他函数体内的函数,嵌套函数可以捕获其外部函数所有的参数已经定义的常量和变量
//捕获值的闭包的最简单形式是嵌套函数
func moreFun(oriValue : Int) -> Int {
var count = 10
func inFunc() -> Int{
count += oriValue
return count
}
return inFunc()
}