Stories

Detail Return Return

swift 閉包本質,閉包表達式,尾隨閉包 - Stories Detail

1. 閉包

  • 一個函數和它所捕獲的變量/常量環境組合起來,稱為閉包

    • 一般指定義在函數內部的函數
    • 一般它所捕獲的是外層函數的局部變量/常量
    typealias fn = (Int) -> Int
    func getFn() -> fn{
    	var count = 0
    		func sum(_ i: Int) -> Int{
        		count += i
        		return count
    		}
    	return sum
    }
    
    var f1 = getFn()
    
    f1(1)
    f1(1)
    f1(1)
    f1(1)
    

    結果:
    image
    解釋:
    閉包能夠使用其外層函數的局部變量,所以函數值能夠增加
    本質:
    編譯器給sum函數外層getFn函數的count屬性分配了堆空間,所以count變量不會在getFn函數執行完後銷燬,因此sum函數能夠對其進行訪問
    分配內存結構: 類似於給class分配的堆空間結構
    image

    • 可以把閉包想象成一個對象的實例

      • 內存在堆空間
      • 捕獲的局部變量/常量就是對象的成員
      • 組成閉包的函數就是類內部定義的方法
        類似與class的形式:
      class Closure{
      var count = 0
      	func sum(_ i:Int) -> Int{
      		count += i
      		return count
      	}
      }
      
      var c1 = Closure()
      c1.sum(1)
      c1.sum(1)
      c1.sum(1)
      

2. 閉包表達式

  • 語法:
    {
    	(參數列表) -> 返回值類型 in
    	函數體代碼
    }
    
  • 簡寫:
    func exec(v1:Int, v2:Int, fn:(Int, Int) -> Int){
    	print(fn(v1, v2))
    }
    // 完整寫法:
    exec(v1:10, v2:20, fn:{
    	(a1:Int, a2:Int) -> Int in
    	return a1 + a2
    })
    // 簡寫1
    exec(v1:10, v2:20, fn:{
    	a1, a2 in return a1 + a2
    })
    // 簡寫2
    exec(v1:10, v2:20,fn:{
    	a1,a2 in a1 + a2
    })
    // 簡寫3
    exec(v1:10, v2:20, fn:{ $0 + $1 })
    // 簡寫4
    exec(v1:10, v2:20, fn: + )
    // 尾隨閉包: 是一個被書寫在函數調用括號外面(後面)的閉包表達式
    // 如果一個很長的閉包表達式作為一個函數的 最後一個 實參,使用尾隨閉包可以增強程序的可讀性
    exec(v1:10, v2:20){ $0 + $1 }
    // 如果函數只有一個參數,且類型是函數類型,可以省略括號
    func add(fn: (Int,Int) -> Int){
    	print(fn(1, 2))
    }
    add{ $0 + $1 }
    // 省略參數
    add{ _,_ in 10 }  //省略掉參數,固定返回10
    

Add a new Comments

Some HTML is okay.