闭包
1.闭包是自包含的功能代码块,可以在代码中使用或者用来作为参数传值。
2.闭包可以捕获和存储上下文中定义的的任何常量和变量的引用。这就是所谓的变量和变量的自封闭,
3.因此命名为”闭包“("Closures)").Swift还会处理所有捕获的引用的内存管理。
如何接收一个函数
// (Int,Int)-> Int func add(a: Int,b: Int) -> Int { return a + b } // (Int,Int) -> Int func multi(a: Int,b: Int) -> Int { return a * b } //语法(Int,Double)-> 返回类型 var f2: (Int,Int)-> Int = add f2(1,2) f2 = multi f2(1,2)
用一个函数(processArray)实现接口(ProceesInt),实现接口(proceesInt)的类经过函数的筛选得到结果
目的:为了让一个函数拥有多种功能
如何去实现:利用了一个接口
func processArray() ->[Int] { let array = [1,8,7,3] var result:[Int] = [] for item in array{ if item % 2 == 0 { result.append(item) } } return result } func processArray2(chulizhe: ProcessInt) ->[Int] { let array = [1,8,7,3] var result:[Int] = [] for item in array{ if chulizhe.guolv(item) { result.append(item) } } return result } protocol ProcessInt { func guolv(data: Int)->Bool } class DaYuYi: ProcessInt { func guolv(data: Int)->Bool{ return data > 1 } } //实现了筛选大于一的数 class OuShu: ProcessInt { func guolv(data: Int)->Bool{ return data % 2 == 0 } } //实现了筛选偶数 processArray2(OuShu())
在函数里传一个函数
func xxx(a: (Int)->Int,b: Int) -> (Int)-> Int { func innerXX(a: Int) -> Int { return 5 } return innerXX } func p(a: Int) -> Int { return 10 } let re = xxx(p,b:11) re(6) //和下面的情况是一样的,都是返回5 xxx(p,b:11)(7)
传一个函数取偶数
func processArray(suanfa: (Int)->Bool) ->[Int] { let array = [1,8,7,3] var result:[Int] = [] for item in array{ if suanfa(item) { result.append(item) } } return result } func process(source: Int) -> Bool { return source % 2 == 0 } let result = processArray(process) result
用闭包来完成传函数的功能
func processArray(suanfa: (Int)->Bool) ->[Int] { let array = [1,8,7,3] var result:[Int] = [] for item in array{ if suanfa(item) { result.append(item) } } return result } let result = processArray({ (a: Int) -> Bool in return a % 2 == 0 }) result
利用函数来实现排序的功能
let array = [1,2,8,3,9] func compare(a: Int,b: Int ) -> Bool { return a < b } array.sort(compare)
利用闭包来传值
let array = [1,2,8,3,9] //传闭包表达式,不需要额外定义函数 let result2 = array.sort({(a: Int,b: Int)->Bool in return a > b }) result2
闭包的优化
let array = [1,2,8,3,9] //参数类型与返回类型的推断 let result2 = array.sort({(a,b) in return a > b }) result2 //单行代码自动会返回此代码的结果 let result3 = array.sort({(a,b) in a > b }) result3 //自动提供简短的参数名 $0,$1,$2.... // let result4 = array.sort({$0 > $1 }) result4 //如果一个函数(sort),它只有一个参数,此参数的类型是函数类型,那么可以把大括号中得内容 //放到小括号外面 let result5 = array.sort(){ $0 > $1 } result2 //或者 :此时是可以去掉括号的 let result6 = array.sort{$0 > $1} result5
闭包的捕获值
func funcFactory() ->() ->Int { var total = 0 func innerFunc() -> Int { total = total + 1 return total } return innerFunc } let r1 = funcFactory() r1() //捕获上面r1的值 输出1 r1() let r2 = funcFactory() r2() r2() let r3 = r2 r3()//这两行代码能部分说明其是一个引用的类型
1.自动把一段代码转换为闭包
2.没有任何参数
3.调用时返回的是整个表达式的值
4.自动闭包一定是作为函数的参数
5.闭包参数添加@autoclosure
func autoClosureDemo2(@autoclosure x:()->String) { let result = x() print(result) } autoClosureDemo2("a")
闭包的另一种用法,可以直接给函数类型赋值。
let f4:()-> Int = {5} //{5}是一个闭包,经过了一系列的优化后,变成了{5} f4() // 返回5
在类里的,在控制台输出5
class XX { var i = 5 //闭包要用到类里面的实例成员,必须加self或者额外声明变量(内存管理时在阐述) // lazy var close: ()->Void = { print(self.i) } } XX().close()