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
不是A' A行'我们每次拨打counter1()
时都会打电话?这意味着每次都应该调用var n = 0
......
为什么计数器会返回不同的值?他们不应该总是回来' 1' ?
答案 0 :(得分:1)
显然,每次调用counter1
时都不会调用A行 。
事件的顺序是:
makeCounter
被调用,它声明并初始化n
(行A),定义adder
,并在包含的上下文中返回adder
n
已经定义并初始化为1 。
刚刚返回的此函数已分配给counter1
。因为A行不是该函数的一部分(adder
/ counter1
),所以在调用该函数时它不会被执行。
对counter1
的每次调用都是在同一个上下文中执行的,这就是n
在调用中保留其值的原因:它们都访问相同的n
。
答案 1 :(得分:1)
您曾致电makeCounter()
一次。这会创建新的闭包,并将其分配给counter1
。这个闭包关闭了可变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
实例。