关于功能和关闭的一个小问题

时间:2017-02-01 05:16:06

标签: swift function closures

func runningMetersWithMetersPerDay ( metersPerDay: Int ) -> () -> 
Int {
    var totalMeters = 0
    return {
        totalMeters += metersPerDay
        return totalMeters
    }
}
var planA = runningMetersWithMetersPerDay (metersPerDay: 2000)
planA()
planA()

第一个planA()打印2000和第二个planA()打印4000。 每次拨打planA()时,该号码都会累积 为什么? var totalMeters = 0在此函数中的用途是什么? planA()runningMetersWith MetersPerDay (metersPerDay: 2000)相同吗? 如果没有,它们之间有什么区别? 谢谢你的帮助。

2 个答案:

答案 0 :(得分:1)

好吧,你的方法返回一个闭包,你要执行两次。 关闭捕获它的环境,在你的情况下,'外部'变量totalMeters并通过不同的调用保持其值。

如果这不是您想要的,那么您必须将totalMeters放入闭包中,如下所示:

func runningMetersWithMetersPerDay ( metersPerDay: Int ) -> () ->
Int {
    return {
        var totalMeters = 0
        totalMeters += metersPerDay
        return totalMeters
    }
}

要回答以下评论中的问题: 我已修改原始功能并调用,打印出一些提示

func runningMetersWithMetersPerDay ( metersPerDay: Int ) -> () ->
    Int {
        print ("rMWMD called")
        var totalMeters = 0
        return {
            totalMeters += metersPerDay
            print ("calculated new result: \(totalMeters)")
            return totalMeters
        }
}

print ("start")
var planA = runningMetersWithMetersPerDay (metersPerDay: 2000) // "rMWMPD called"
print ("got planA")
planA() // "calculated new result:2000"
planA() // "calculated new result:4000"

runningMetersWithMetersPerDay (metersPerDay: 2000)() // "calculated new result: 2000"
planA() // "calculated new result:6000"
print ("end")

planA是函数runningMetersWithMetersPerDay的结果(类型(())->Int的闭包 - void参数并返回Int ),然后执行闭包两次并获得结果(2000,4000)。

现在,再次调用函数 runningMetersWithMetersPerDay(metersPerDay:) ,返回 new 闭包,然后返回此返回值。它返回2000,因为它是一个新的闭包(尽管没有分配给变量)。 可以将其视为以下内容:

    runningMetersWithMetersPerDay (metersPerDay: 2000) /* "rMWMPD called" and now call the closure: */ () // "calculated new result: 2000"

最后你第三次执行planA,并且由于它仍然拥有它自己的状态(例如自己的totalMeters值),它返回6000.

答案 1 :(得分:0)

这里发生的事情很正常。 让我们一步一步走。

首先,你运行:

var planA = runningMetersWithMetersPerDay (metersPerDay: 2000)

你在这里执行什么?

var totalMeters = 0
return {
    totalMeters += metersPerDay
    return totalMeters
}

你在planA中有什么?

  1. 具有可变totalMeters的上下文
  2. 准备在此上下文中执行的功能
  3. 首次运行,totalMeters = 0

    {
        totalMeters += metersPerDay
        return totalMeters
    }()
    

    第二次运行,totalMeters = 2000

    {
        totalMeters += metersPerDay
        return totalMeters
    }()
    

    新结果= 4000