【问题标题】:Regarding Swift's value capture on closures关于 Swift 对闭包的价值捕获
【发布时间】:2014-10-23 19:58:12
【问题描述】:

我正在阅读一本关于 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? 是因为双态常数的实例吗?还是因为在双态初始化时 currentState 被初始化为 0 并且编译器推断出

var currentState: Int = 0

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

【问题讨论】:

  • 我想我已经弄清楚了,但是有人可以确认吗?是因为函数返回闭包本身而不是整个函数吗?这对于闭包如何仍然保持函数中定义的局部变量更有意义。

标签: swift closures


【解决方案1】:

这在Capturing Values的第一段中有解释:

闭包可以从定义它的周围上下文中捕获常量和变量。然后闭包可以在其主体中引用和修改这些常量和变量的值,即使定义常量和变量的原始范围不再存在。

并在下面的几段注释中:

Swift 决定什么应该通过引用捕获,什么应该通过值复制。

因此,闭包获取了currentState 的引用(并且不是副本)。对闭包内该变量的任何更改都在闭包外部定义的实例中完成,即使范围不再存在(因为已执行 makeStateMachine 函数)。

【讨论】:

    【解决方案2】:

    该书章节的作者在这里 :-)

    是的,我可以确认您的评论是正确的,该函数返回一个闭包。我添加了一些希望能澄清事情的 cmets:

    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 返回的闭包的引用。

    【讨论】:

      【解决方案3】:

      似乎没有人解释它......

      函数makeStateMachine 返回一个捕获两个变量的闭包:maxStatecurrentState。当使用maxState1 调用时,返回的闭包将递增currentState,将其与1 进行比较,然后如果超过1,则将currentState 重置为0。给定对返回闭包的多次调用,返回值序列为1, 0, 1, 0, ...。更一般地,对于任何maxState,序列为1, ..., maxState, 0, ..., maxState, ...

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-03-22
        • 2014-09-26
        • 2023-03-12
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多