闭包block多种应用方式

闭包是一个十分强大的功能,灵活多变,便于使用;实际上闭包是一种匿名的函数.数组

其类型和对应的函数类型保持一致.网络

使用闭包,咱们能够动态的改变函数或方法中的代码,从而适应不一样环境下的要求.闭包

1.闭包的形式app

  1. {    (形参列表) ->返回值类型  in  
  2.           //其余代码    
  3. }  

对比函数的定义,以下异步

  1. func 函数名(参数列表) [ - > 返回值类型]  
  2. {  
  3.     //函数体  
  4. }  

咱们能够看到,闭包与函数的主要区别是 少了  func  函数名这一块;也就是说,函数与闭包的主要区别就是闭包是匿名的.函数

闭包示例:动画

  1. {  
  2.     (a:Int,b:Int)->Int in  
  3.   
  4.     return a+b  
  5.       
  6. }  

2.闭包的使用,闭包赋值给一个变量以后,该变量能够直接当函数使用指针

(1)定义一个闭包,功能是计算两个数之和,使用一个变量来接受该闭包.排序

  1. var plus =  
  2. {  
  3.     (a:Int,b:Int)->Int in  
  4.   
  5.     return a+b  
  6.       
  7. }  

对于咱们的写法系统则默认处理 plus为一个函数,见下图作用域

\

(2)使用闭包,当作函数来使用闭包变量

  1. var c = plus(2,3)  
  2. println(c)  

固然咱们也能够把 plus变量 用来接收其余的闭包

(3)闭包的外部形参名是没有做用的

和函数相似,闭包也可使用外部形参名,可是闭包的外部形参名是没有任何做用的,咱们使用闭包时,不能输入对于的外部形参名,不然会报错

  1. var plus =  
  2. {  
  3.     (#a:Int,第二个参数 b:Int)->Int in  
  4.   
  5.     return a+b  
  6.       
  7. }  

对于上面的代码,咱们须要使用以下的方式使用;不能传入外部形参名

  1. var c = plus(22,3)  
  2. println(c)  


而对于咱们愿景来讲使用:

  1. var c2 = plus(a:1,第二个参数 :3)  


反而会报错!这也许在后期的版本中可能会有所改变;可是现在,咱们最好仍是别多此一举了!

(4)定义完闭包以后直接调用该闭包

闭包还支持定义之后直接传入对应的参数来调用该闭包,调用闭包时须要使用括号.

以下面的代码,在定义完代码以后直接调用该闭包,结果返回给  plus变量

  1. var plus =  
  2. {  
  3.     (a:Int,b:Int)->Int in  
  4.   
  5.     return a+b  
  6.       
  7. }(2,3)  

输出:

  1. 5  

3.闭包的类型推断

闭包的类型,实际上一种函数类型;其类型能够根据用来接收闭包的变量的类型或者实参的类型来自动推断出  闭包对应的类型.

(1)闭包根据变量是 函数类型的 来推断其 参数类型,返回值类型

  1. var plus2:(Int,Int)->Int =  
  2. {  
  3.     (a,b) in  
  4.       
  5.     return a+b  
  6.       
  7. }  

或者省略括号

  1. var plus2:(Int,Int)->Int =  
  2. {  
  3.     a,b in  
  4.       
  5.     return a+b  
  6.       
  7. }  

此时的plus2是一个函数,因此咱们使用以下方式调用闭包

  1. println(plus2(3,4))  


因为plus2的类型是  (Int,Int)->Int函数类型,那么 闭包可自动推断  出  参数  a,b的类型是  Int,返回值是  Int类型

(2)闭包根据传入的实参类型来自动推断闭包类型

  1. var app:Int =  
  2. {  
  3.     a,b in  
  4.       
  5.     return a+b  
  6. }(111,222)  

输出:对应的app的值

  1. println(app)  

咱们在定义闭包后直接调用闭包须要传入实参,闭包能够根据实参的类型来推断

 其中  a,b参数的类型;返回值类型和 app的类型一致 推断出是 Int类型

4.闭包 省略 return 语句

当 闭包的内容只有一行,且该行语句是返回一个值,那么此时 return 能够省略

  1. var plus3:(Int,Int)->Int =  
  2. {  
  3.     a,b in  
  4.       
  5.     a+b  
  6.       
  7. }  

如上面的闭包省略了 形参类型和 return ;

该闭包只有 一行语句且该语句就是闭包的返回值

5.省略形参名和 in 关键字

Swift不只能够省略上述状况的一些东西,还容许省略  形参名 和  in;

Swift能够 经过  $0  ,$1  ...来引用第一个 ,第二个形参 ,第N个形参...

  1. var app3:Int =  
  2. {  
  3.   return $0*$0  
  4. }(111)  

$0表明 $0


或者省略 return 

  1. var app2:Int =  
  2. {  
  3.     $0*$1  
  4. }(111,222)  

 

$1表明222
原则是 闭包 能够根据 实参,或者 接收该闭包的变量的类型来自动推断类型

6.尾随闭包

(1)闭包做为函数的一个参数

首先咱们来定义一个 参数带有 函数类型的 函数

  1. func myFunc(#a:Int,#b:Int,#fun:(Int,Int)->Int)->Int  
  2. {  
  3.       
  4. }  

参数 fun是一个 函数类型的参数,咱们能够传入一个函数 或者  闭包

完整定义

  1. func myFunc(#a:Int,#b:Int,#fun:(Int,Int)->Int)->Int  
  2. {  
  3.     var c = fun(a,b)  
  4.     return c  
  5. }  

调用时传入一个  闭包 

  1. var d = myFunc(a: 11, b: 22, fun: {  return $0+$1})  

或者:

  1. var d = myFunc(a: 11, b: 22, fun: {  $0+$1})  

fun闭包彻底能够根据 myFunc形参类型来 省略 fun的 类型甚至 省略  return (由于只有一行语句)

(2)当函数的最后一个参数是函数类型时,可使用尾随闭包,简化写法

能够看到步骤1  调用的方式 是  :

  1. myFunc(a:,b:,fun:{闭包体})   

此种状况使用尾随闭包则能够写的更简洁

改成

  1. myFunc(a:,b:)  
  2. {  
  3.       //闭包体  
  4. }  

 

  1. var cc = myFunc(a: 1, b: 2){$0+$1}  


如上代码,  返回值  $0+$1的闭包; 

由于  a,b是属于  myFunc函数的 ,因此在闭包中 体中 并不知道 a,b这几个变量,只能使用  $0的形式

  1. 尾随闭包: 就是当函数的最后一个参数是函数类型时,调用函数 时,可传入一个闭包 ,该闭包能够放在 圆括号以外  

7.捕获所对应的做用域的值

闭包能够访问 其所处的上下文(还有全局的)的变量和常量,称之为 捕获

  1. var dd = 2  
  2.   
  3. func myFunc(#a:Int,#b:Int,#fun:(Int,Int)->Int)->Int  
  4. {  
  5.       
  6.     var aa = 22, bb = 33  
  7.       
  8.     var c = fun(dd,bb)  //闭包能够访问  aa,bb  
  9.     return c  
  10. }  

 

如上代码 ,闭包 fun能够访问    全局变量 dd;

固然也能够访问 bb ,此称之为 捕获.

8.闭包的类型

Swift闭包 和 Oc的闭包相似,都是引用类型的;因此咱们把复制 闭包变量时,其实是复制的对应的指针; 复制的 副本 和 源 闭包变量指向同一变量

9.闭包的用途

闭包可使用在  网络异步任务  , 界面传值  ,GCD ,数组排序,动画,组件封装 等地方;

灵活的使用闭包,可让咱们事半功倍

相关文章
相关标签/搜索