[英]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
現在, counter1
和counter2
都有自己獨立的n
實例。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.