我正在读一本关于swift的书,并且遇到了关闭值捕获的例子。
func makeStateMachine(maxState: Int) -> StateMachineType {
var currentState: Int = 0
return {
currentState++
if currentState > maxState {
currentState = 0
}
return currentState
}
}
let bistate = makeStateMachine(1)
println(bistate());
println(bistate());
println(bistate());
println(bistate());
输出应为< 1 0 1 0'
我理解返回块如何捕获本地值' currentState'函数执行后的值,但为什么在下一个函数调用时该值不能设置为0? 是因为bistate常数的实例?或者是因为currentState在bistate初始化时初始化为值0,编译器推断出
var currentState: Int = 0
被忽略了?我很困惑第一次通话后如何处理上述行。
答案 0 :(得分:4)
Capturing Values的第一段解释了这一点:
闭包可以从定义它的周围上下文中捕获常量和变量。然后闭包可以引用并修改其体内的常量和变量的值,即使定义常量和变量的原始范围不再存在。
并在下面的几段中注明:
Swift确定应该通过引用捕获什么以及应该通过值复制什么。
因此,闭包抓取currentState
的引用(和不副本)。闭包内对该变量的任何更改都是在闭包外定义的实例中完成的,即使作用域不再存在(因为makeStateMachine
函数已被执行)。
答案 1 :(得分:1)
该书章节的作者: - )
是的,我可以确认你的评论是正确的,该函数返回一个闭包。我添加了一些评论,希望澄清一些事情:
func makeStateMachine(maxState: Int) -> StateMachineType {
// this variable is initialised when makeStateMachien is invoked
var currentState: Int = 0
// the function returns this closure
return {
// by using 'currentState' this variable is captured
currentState++
if currentState > maxState {
currentState = 0
}
return currentState
}
}
调用此函数时:
let bistate = makeStateMachine(1)
常量bistate
现在包含对makeStateMachine
返回的闭包的引用。
答案 2 :(得分:1)
似乎没有人解释过它......
函数makeStateMachine
返回一个捕获两个变量的闭包:maxState
和currentState
。使用maxState
1
调用时,返回的闭包将增加currentState
,将其与1
进行比较,然后将currentState
重置为0
超出1
。给定对返回闭包的多次调用,返回值序列为1, 0, 1, 0, ...
。更一般地说,对于任何maxState
,序列为1, ..., maxState, 0, ..., maxState, ...