Swift 閉包理解

2022-07-24 20:18:15 字數 3068 閱讀 8014

/*

閉包(closures)

* 閉包是自包含的功能**塊,可以在**中使用或者用來作為引數傳值。

* 在swift中的閉包與c、oc中的blocks和其它程式語言(如python)中的lambdas類似。

* 閉包可以捕獲和儲存上下文中定義的的任何常量和變數的引用。這就是所謂的變數和變數的自封閉,

* 因此命名為」閉包「("closures)").swift還會處理所有捕獲的引用的記憶體管理。

* * 全域性函式和巢狀函式其實就是特殊的閉包。

* 閉包的形式有:

* (1)全域性函式都是閉包,有名字但不能捕獲任何值。

* (2)巢狀函式都是閉包,且有名字,也能捕獲封閉函式內的值。

* (3)閉包表示式都是無名閉包,使用輕量級語法,可以根據上下文環境捕獲值。

* * swift中的閉包有很多優化的地方:

* (1)根據上下文推斷引數和返回值型別

* (2)從單行表示式閉包中隱式返回(也就是閉包體只有一行**,可以省略return)

* (3)可以使用簡化引數名,如$0, $1(從0開始,表示第i個引數...)

* (4)提供了尾隨閉包語法(trailing closure syntax) */

//下面用swift標準庫中的sort方法來一步步簡化閉包寫法 //

sort函式需要兩個引數 //

引數一:陣列 //

引數二:乙個閉包:帶有兩個引數,這兩個引數型別與陣列中的元素型別相同,返回值是bool

var names = ["

swift

", "

arial

", "

soga

", "

donary

"]

//第一種方式:使用函式

func backwards(firststring: string, secondstring: string) ->bool //

這裡第二個引數,傳了乙個函式 //

reversed is equal to ["swift", "soga", "donary", "arial"]

var reversed =sort(nams, backwards)

//第二種方式:使用閉包方式 //

完整閉包寫法是在花括號內有引數列表和返回值,用關鍵字in表明閉包體的開始 //

(firststring: string, secondstring: string) 閉包引數列表 //

-> bool 指明閉包返回值型別是bool //

in關鍵字表明閉包體的開始

reversed = sort(names, )

//這裡可以進一步簡化寫法,因為閉包**比較短,可以寫到一行上

reversed = sort(names, )

//下面再進一步簡化寫法 :根據環境上下文自動推斷出型別

//引數列表都沒有指明型別,也沒有指明返回值型別,這是因為swift可以根據上下文推測出

//firststring和secondstring的型別會是names陣列元素的型別,而返回值型別會根據return語句結果得到

reversed = sort(names, )

//再進一步簡化:隱式返回(單行語句閉包)

//因為閉包體只有一行**,可以省略return

reversed = sort(names, )

//再進一步簡化:使用簡化引數名($i,i=0,1,2...從0開始的)

//swift會推斷出閉包需要兩個引數,型別與names陣列元素相同

reversed = sort(names, )

//最簡單的一種寫法:使用操作符

reversed = sort(names, >)

/** 尾隨閉包(trailing closures)

* 如果函式需要乙個閉包引數作為引數,且這個引數是最後乙個引數,而這個閉包表示式又很長時,

* 使用尾隨閉包是很有用的。尾隨閉包可以放在函式引數列表外,也就是括號外。如果函式只有乙個引數,

* 那麼可以把括號()省略掉,後面直接跟著閉包。 */

//array的方法map()就需要乙個閉包作為引數

let strings = numbers.map

return

output

}

/*捕獲值

* 閉包可以根據環境上下文捕獲到定義的常量和變數。閉包可以引用和修改這些捕獲到的常量和變數,

* 就算在原來的範圍內定義為常量或者變數已經不再存在(很牛逼)。

* 在swift中閉包的最簡單形式是巢狀函式。 */

func increment(#amount: int) -> (() ->int)

return incrementamount //

返回的是乙個巢狀函式(閉包)

}

//閉包是引用型別,所以incrementbyten宣告為常量也可以修改total

let incrementbyten = increment(amount: 10

)

incrementbyten()

//return 10,incrementbyten是乙個閉包

//這裡是沒有改變對increment的引用,所以會儲存之前的值

incrementbyten() //

return 20

incrementbyten() //

return 30

let incrementbyone = increment(amount: 1

) incrementbyone()

//return 1

incrementbyone() //

return 2

incrementbyten() //

return 40

incrementbyone() //

return 3

swift閉包,我的理解

什麼是閉包?可以捕獲和儲存其所在上下文中任意常量和變數的引用的表示式 我把所有的函式都理解為是閉包 全域性函式 不能捕獲值的閉包 方法 定義在例項中的函式,所以方法也能當閉包表示式處理 巢狀函式 作用區域小點,可以捕獲其封閉函式域內值的閉包。例如 引數和返回值為空元組 的表示式 func open ...

swift深入理解閉包

我們可用swift的閉包來定義變數的值。先來乙個簡單的例子大家先感受感受。定義乙個字串的變數的方法 直接賦值 var string a string 還可以用閉包的方式定義 var string1 string 閉包還可以這麼定義,省略了等號和括號 var string2 string 閉包中可以定...

swift 深入理解Swift的閉包

我們可用swift的閉包來定義變數的值。先來乙個簡單的例子大家先感受感受。定義乙個字串的變數的方法 直接賦值 var str jobdeer 還可以用閉包的方式定義 var str string 閉包還可以這麼定義,省略了等號和括號 var str string 閉包中可以定義get方法。var s...