关于Swift在闭包上的值捕获

时间:2014-10-23 19:58:12

标签: swift closures

我正在读一本关于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

被忽略了?我很困惑第一次通话后如何处理上述行。

3 个答案:

答案 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返回一个捕获两个变量的闭包:maxStatecurrentState。使用maxState 1调用时,返回的闭包将增加currentState,将其与1进行比较,然后将currentState重置为0超出1。给定对返回闭包的多次调用,返回值序列为1, 0, 1, 0, ...。更一般地说,对于任何maxState,序列为1, ..., maxState, 0, ..., maxState, ...