閉包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 ,數組排序,動畫,組件封裝 等地方;

靈活的使用閉包,可讓咱們事半功倍

相關文章
相關標籤/搜索