Swift-閉包Closure

先復(fù)習(xí)一下函數(shù)Swift-func

閉包可以定義一個(gè)函數(shù)

閉包可以定義一個(gè)函數(shù)

閉包可以定義一個(gè)函數(shù)

閉包概念:

  • 一個(gè)函數(shù)和它所捕獲的變量/常量環(huán)境組合起來,稱為閉包
  • 一般指定義在函數(shù)內(nèi)部的函數(shù)
  • 一般它捕獲的是外層函數(shù)的局部變量/常量

演繹過程:

typealias Fn = (Int) -> Int
func getFn() -> Fn {
    var num = 10
    func plus(i: Int) -> Int {
        num += I
        return num
    }
    return plus//這是函數(shù)哦 不能是實(shí)現(xiàn)
    return plus(I:)
}

var fnx = getFn()
print(fnx(1))
  • 2層函數(shù) 外層函數(shù)getFn返回值是函數(shù)類型 內(nèi)層函數(shù)plus也要返回函數(shù)類型
  • plus函數(shù)和num形成了閉包

簡易一下程序

func getFn() -> Fn {
    var num = 10
    return {
        num += $0
        return num
    }
}

類比一個(gè)類的實(shí)例對(duì)象

  • 內(nèi)存在堆空間
  • 捕獲的局部變量/常量就是對(duì)象的成員(存儲(chǔ)屬性)
  • 組成閉包的函數(shù) 就是類內(nèi)部定義的方法
class Closure {
    var num = 0
    func plus(_ i:Int) -> Int {
        num += I
        return num
    }
}
var cs1 = Closure()
print(cs1.plus(1))

閉包

Swift中,可以通過func定義一個(gè)函數(shù) 也可以通過閉包表達(dá)式定義一個(gè)函數(shù)

func add(_ v1: Int,_ v2: Int) -> Int {
    v1 + v2
}
var fx = {
    (v1: Int,v2: Int) -> Int in
    return v1 + v2
}
print(fx(10,20))
print(fx)
print(add)

把實(shí)現(xiàn)帶著隨便測(cè)試
var fx1 = {
    (v1: Int,v2: Int) -> Int in
    return v1 + v2
}(10,10)
print(fx1)
  • 上面打印fx 打印結(jié)果: (Function)
  • 上面打印add 打印結(jié)果: (Function)
  • 閉包類似add 然后調(diào)用它 傳入?yún)?shù)fx(10,20)
image.png

閉包作為參數(shù)(閉包簡寫真特么簡 其實(shí)不簡寫容易讀)

//exec定義
func exec(v1: Int,v2: Int,fn:(Int,Int) -> Int) {
    print(fn(v1,v2))
}

實(shí)現(xiàn)exec方法

  • 普通函數(shù)
var fn:(Int,Int)->Int = add
exec(v1: 10, v2: 10, fn: fn)
  • 閉包
//寫全一點(diǎn)
exec(v1: 10, v2: 20, fn: {
    (v1: Int,v2: Int) -> Int in
    return v1 + v2
})
//省略return
exec(v1: 10, v2: 20, fn: {
    (v1: Int,v2: Int) -> Int in
    v1 + v2
})
//省略參數(shù)
exec(v1: 10, v2: 20, fn: {
    v1,v2 -> Int in
    v1 + v2
})
//省略返回值
exec(v1: 10, v2: 20, fn: {
    v1,v2  in
    v1 + v2
})
//下標(biāo)
exec(v1: 10, v2: 10, fn: {
    $0 + $1
})
//一步到位了靠
exec(v1: 10, v2: 10, fn: +)

尾隨閉包

  • 如果將一個(gè)很長的閉包表達(dá)式作為函數(shù)的最后一個(gè)實(shí)參,使用尾隨閉包可以增強(qiáng)函數(shù)的可讀性
  • 尾隨閉包是一個(gè)被書寫在函數(shù)調(diào)用括號(hào)外面(后面)的閉包表達(dá)式
  • 如果閉包表達(dá)式是函數(shù)的唯一實(shí)參,而且使用了尾隨閉包的語法,那就不需要在函數(shù)名后面寫圓括號(hào)
func exec1(fn:(Int,Int) -> Int) {
    print(fn(1,2))
}
exec1(fn: {
    (v1: Int,v2: Int) -> Int in
    return v1 * v2
})
exec1{
    (v1: Int,v2: Int) -> Int in
    return v1 * v2
}
......下面同樣可以省略 自己搞吧

自動(dòng)閉包(語法真雞賊)

后面在搞吧 語法真特么難懂太簡易了

  • @autoclosure 會(huì)自動(dòng)將20 封裝成閉包{20}
  • @autoclosure 只支持 () -> T 格式的參數(shù)
  • @autoclosure 并非只支持最后一個(gè)參數(shù)
  • 空合并運(yùn)算符?? 使用了@autoclosure技術(shù)
  • 有@autoclosure 無@autoclosure,構(gòu)成了函數(shù)重載
  • 為了避免與期望沖突,使用了@autoclosure的地方最好明確注釋清楚,這個(gè)值會(huì)被推遲執(zhí)行
func getFirstPositive (_ v1: Int,_ v2: Int) -> Int {
    return v1 > 0 ?v1 : v2
}
print(getFirstPositive(10, 20))
print(getFirstPositive(-2, 20))
print(getFirstPositive(0, -4))
//改成函數(shù)類型的參數(shù),可以讓v2延遲加載
func getFirstPositive(_ v1: Int,_ v2: () -> Int) -> Int? {
    return v1 > 0 ? v1: v2()
}
print(getFirstPositive(-4, {20})!)

func getFirstPositive1(_ v1: Int,_ v2:@autoclosure () -> Int) -> Int? {
    return v1 > 0 ? v1: v2()
}
print(getFirstPositive1(-4, 20)!)

參數(shù)修飾符保持一致

//如果返回值是函數(shù)類型,那么參數(shù)的修飾要保持統(tǒng)一
func total(_ num: Int) -> (inout Int) -> Void {
    func plus(v: inout Int) {
        v += num
    }
    return plus
}
var vvvv = 5
total(20)(&vvvv)
print(vvvv)

忽略參數(shù)(語法真雞賊)

func exec2(fn:(Int ,Int) -> Int) {
    print(fn(1,2))
}
exec2{_,_ in 100}

練習(xí)

var functions:[() -> Int] = []
for i in 1...3 {
    functions.append{I}
}
for i in functions {
    print(i)
}
class Closure2 {
    var i: Int
    init(_ i: Int) {
        self.i = I
    }
    func get() -> Int {
        return I
    }
}
var clses:[Closure2] = []
for i in 1...3 {
    clses.append(Closure2(i))
}
for i in clses {
    print(i.get())
}

補(bǔ)充案例

案例一:網(wǎng)絡(luò)請(qǐng)求 省略參數(shù) 逃逸閉包

image.png

Function types cannot have argument labels; use '_' before 'result'
從Swift3.0開始, 蘋果官方建議方法中函數(shù)類型的參數(shù)不要帶參數(shù)名稱, 尤其是不能帶外部參數(shù)名.
解決方案:

  • 省略標(biāo)簽參數(shù)
  • 這個(gè)閉包里面的標(biāo)簽參數(shù)是為了增加代碼可讀性
class func requestData(parameters: [String:Any]?,finishedCallBack:(_ result:Any)->()) {
    finishedCallBack("回調(diào)請(qǐng)求內(nèi)容")
}

新的問題


image.png

逃逸閉包捕獲非逃逸閉包
captures:捕獲
Escaping:逃逸


image.png

語法小計(jì)

  • 閉包實(shí)現(xiàn) 可以把參數(shù)省略
NetworkTools.requestData(url: requestUrl, method: .post, parameters: parameters) { response, status in
    
}
NetworkTools.requestData(url: requestUrl, method: .post, parameters: parameters) { (response, status) in
    
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 閉包可以從定義它們的上下文中捕獲和存儲(chǔ)對(duì)任何常量和變量的引用。 這被稱為關(guān)閉這些常量和變量。 Swift處理所有的...
    Joker_King閱讀 638評(píng)論 0 2
  • 閉包 閉包可以捕獲和存儲(chǔ)其所在上下文中任意常量和變量的引用,被稱為包裹常量和變量。Swift 會(huì)為你管理在捕獲過程...
    DevXue閱讀 258評(píng)論 0 0
  • 前言:swift是一門很優(yōu)雅,很簡潔,功能很強(qiáng)大的語言,同時(shí)也是一門很復(fù)雜的語言。進(jìn)門比較簡單,看完蘋果官方的文檔...
    一劍孤城閱讀 6,362評(píng)論 0 10
  • 本章將會(huì)介紹 閉包表達(dá)式尾隨閉包值捕獲閉包是引用類型逃逸閉包自動(dòng)閉包枚舉語法使用Switch語句匹配枚舉值關(guān)聯(lián)值原...
    寒橋閱讀 1,629評(píng)論 0 3
  • 推薦指數(shù): 6.0 書籍主旨關(guān)鍵詞:特權(quán)、焦點(diǎn)、注意力、語言聯(lián)想、情景聯(lián)想 觀點(diǎn): 1.統(tǒng)計(jì)學(xué)現(xiàn)在叫數(shù)據(jù)分析,社會(huì)...
    Jenaral閱讀 5,991評(píng)論 0 5

友情鏈接更多精彩內(nèi)容