簡體   English   中英

閉包如何捕獲先前調用的值?

[英]How do closures capture values from previous calls?

typealias IntMaker = (Void)->Int

func makeCounter() ->IntMaker{
    var n = 0 // Line A

    func adder()->Integer{
        n = n + 1
        return n 
    }
    return adder
}

let counter1 = makeCounter()

counter1() // returns 1
counter1() // returns 2
counter1() // returns 3

每次調用counter1()時都不會調用'A行'嗎? 意思是每次都應該調用var n = 0 ...

為什么計數器返回不同的值? 他們不應該總是回歸'1'嗎?

顯然,每次調用counter1不會調用A行。

事件的順序是:

  • makeCounter ,它聲明並初始化n (行A),定義adder ,並在包含已經定義並初始化為1的n的上下文中返回adder

  • 剛剛返回的此函數被分配給counter1 因為A行不是該函數的一部分( adder / counter1 ),所以在調用該函數時不會執行它。

  • 每次對counter1調用都在同一個上下文中執行,這就是為什么n在調用中保留其值的原因:它們都訪問相同的n

你曾經調用過makeCounter()一次。 這會創建新的閉包,並將其分配給counter1 這個閉包關閉了mutable var n ,只要存在這個閉包,它就會被捕獲。

調用counter1()將執行它,但它保留相同的捕獲n ,並使其變異。 只要它存在,這個特殊的“加法器”將始終捕獲相同的n

要獲得您建議的行為,您需要創建捕獲n新實例的新閉包:

let counter1 = makeCounter()

counter1() // returns 1
counter1() // returns 2
counter1() // returns 3

var counter2 = makeCounter()
counter2() // returns 1
counter2 = makeCounter()
counter2() // returns 1
counter2 = makeCounter()
counter2() // returns 1

現在, counter1counter2都有自己獨立的n實例。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM