Swift-閉包

Swift 閉包

函數 ()->()

Swift 中的閉包和 Objective-C 中的 block 類似,閉包是功能性自包含模塊,可以在代碼中被傳遞和使用。 在 Swift 中 函數只是閉包的一種特殊形式。

1.全局函數是一個有名字但不會捕獲任何值的閉包
2.內嵌函數是一個有名字可以捕獲到所在的函數域內值的閉包
3.閉包表達式是一個沒有名字的可以捕獲上下文中的變量或者常量的閉包

定義函數

我們在 Swift 中使用 func 關鍵字來定義函數,函數可以沒有參數和返回值,也可以有一個或者多個參數和返回值。在Swift中多個參數的返回值叫做元組(tuples)

 func foo(firstname:String ,lastname:String)->(fullname:String){
      return("\(firstname) \(lastname)")
 }

函數調用

 let fullname = foo("zhao”,”sunny”)

函數類型

每一個函數都有它的類型,函數的類型由函數本身的參數類型和返回值類型來決定的。

  func sum(x:Int,y:Int) -> (result:Int){return x + Y}

上面這個函數的函數類型就是

  (Int,Int)->(Int)

函數類型在構建函數的時候當成參數類型或者返回值類型來使用。

返回函數類型

func foo()->((String,String) -> String){
   func bar(firstname:String,lastname:String) ->(fullname:String){
    return("\(firstname) \(lastname)")
  }
  return bar
}
let namecombination = foo()
namecombination("wang","er")

可變參數函數

可變參數函數是指函數可以接收不固定個參數。在參數類型后面添加 來標記這個參數為可變參數。我們可以在函數中像訪問數組一樣訪問可變參數。

func foo(names:String...) ->() {
  for name in names {
   println("\(name)")
  }
}
func foo("zhao","zhang","wang")

In-out 參數函數

傳入函數的參數值只能在函數域內改變。參數傳遞是值傳遞,也就是說我們在函數內部修改了一個參數的值,在函數結束后,函數外部訪問到的參數值還是傳入函數之前的值,它并沒有隨著函數內的修改而改變。在Objective-C 我們通過指針來保存函數內修改過的值以供函數結束后外部訪問。常見的例子就是 NSError 的使用。
Swift 中我們也可以做類似的操作。我們需要inout 關鍵字來標記要修改的參數。

func swapTwoInts(inout a: Int, inout b: Int) { 
    let temporaryA = a
     a = b 
        b = temporaryA
 }
 var someInt = 3 
 var anotherInt = 107 
 swapTwoInts(&someInt, &anotherInt)  

閉包 { ()->() in }

定義一個閉包

閉包是一個使用花括號{} 包圍起來,并且使用函數類型()->()來定義的代碼模塊。->符號分割了輸入參數和返回值類型。在關鍵字 in 來區分閉包的頭和閉包函數體。

 {(params) -> returnType in 
    statements
 }

一個數組的map閉包的例子

let names = ["zhao","wang","Li"]
names.map({
  (name:String) -> String in 
   "\(name) has been map !"
})

已知參數類型的閉包

map的閉包是作為函數參數傳入的,所以 Swift 是可以做類型推斷的,這樣的話我們就不需要在閉包中在描述閉包的函數類型,也就是我們可以省略 (String) -> (String) 部分,來簡寫閉包表達式

let names = ["zhao","wang","Li"]
names.map({
  name in 
    "\(name) has been map !"
}) 

如果閉包有返回值我們也可以簡寫省略掉return

例如

let names = ["zhao","wang","Li"]
let orderNames = sort(names,{s1,s2 in s1 > s2})

閉包參數名簡寫

Swift 為內聯函數提供了參數名稱簡寫功能,您可以直接通過 $0,$1,$2等名字來引用的閉包的參數的值。

let names = ["zhao","wang","Li"]
names.map({"\($0) has been map !"})
sort(names,{$0 > $1})

如果閉包是函數的最后一個參數,我們可以省略掉圓括號

names.map{"\($0) has been map !"}
sort(names){$0 > $1}

對于排序函數 sort() 來說作為參數的閉包表達式只進行了兩個值的比較,比較是通過操作符 >來進行的。在Swift中可以進行操作符重載,我們會發現在String 中定義了>的函數實現,也就是 > 本身就是一個函數 ,它接收兩個String 類型的參數 并返回一個Bool類型的值。這和 Sort 函數的第二個參數的類型是一致的。所以,我們還可以進一步簡寫 Sort()

sort(names,>)

閉包跟函數是引用類型

無論您將函數/閉包賦值給一個常量還是變量,您實際上都是將常量/變量的值設置為對應函數/閉包的引用。這也意味著如果您將閉包賦值給了兩個不同的常量/變量,兩個值都會指向同一個閉包.

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • 閉包是功能性自包含模塊,可以在代碼中被傳遞和使用。Swift中的閉包與 C 和 Objective-C中的 blo...
    AirZilong閱讀 353評論 0 2
  • 閉包是自包含的函數代碼塊,可以在代碼中被傳遞和使用。Swift 中的閉包與 C 和 Objective-C 中的代...
    窮人家的孩紙閱讀 1,729評論 1 5
  • 閉包可以從定義它們的上下文中捕獲和存儲對任何常量和變量的引用。 這被稱為關閉這些常量和變量。 Swift處理所有的...
    Joker_King閱讀 597評論 0 2
  • * 閉包 是自包含的函數代碼塊,可以在代碼中被傳遞和使用。swift中的閉包和Objective-C中的代碼塊(b...
    EndEvent閱讀 865評論 4 8
  • 閉包是自包含的代碼塊,可以在代碼中被傳遞和使用。Swift中的閉包與C和Objective-C中代碼塊(block...
    Raaaaamsey閱讀 854評論 0 2