闭包如何从之前的调用中捕获值?
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()
时都会调用'Line A'吗?意思是 var n = 0
应该每次都被调用...
为什么计数器 returns 的值不同?他们不应该总是返回“1”吗?
显然,A 行 不是 每次调用 counter1
时都被调用。
事件的顺序是:
makeCounter
被调用,它声明并初始化 n
(A 行),定义 adder
和 returns adder
在包含 n
的上下文中已经定义并初始化为 1。
正是这个刚刚返回的函数赋值给了counter1
。因为 A 行不是该函数的一部分 (adder
/counter1
),所以在调用该函数时不会执行它。
对 counter1
的每次调用都在相同的上下文中执行,这就是为什么 n
在调用中保留其值的原因:它们都访问相同的 n
.
您打过 makeCounter()
一次电话。这将创建您的新闭包,并将其分配给 counter1
。此闭包关闭可变 var n
,只要此闭包存在,就会保持捕获状态。
调用 counter1()
将执行它,但它会保留捕获的相同 n
,并对其进行变异。这个特定的 "adder" 将始终捕获相同的 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
实例。
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()
时都会调用'Line A'吗?意思是 var n = 0
应该每次都被调用...
为什么计数器 returns 的值不同?他们不应该总是返回“1”吗?
显然,A 行 不是 每次调用 counter1
时都被调用。
事件的顺序是:
makeCounter
被调用,它声明并初始化n
(A 行),定义adder
和 returnsadder
在包含n
的上下文中已经定义并初始化为 1。正是这个刚刚返回的函数赋值给了
counter1
。因为 A 行不是该函数的一部分 (adder
/counter1
),所以在调用该函数时不会执行它。对
counter1
的每次调用都在相同的上下文中执行,这就是为什么n
在调用中保留其值的原因:它们都访问相同的n
.
您打过 makeCounter()
一次电话。这将创建您的新闭包,并将其分配给 counter1
。此闭包关闭可变 var n
,只要此闭包存在,就会保持捕获状态。
调用 counter1()
将执行它,但它会保留捕获的相同 n
,并对其进行变异。这个特定的 "adder" 将始终捕获相同的 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
实例。