How do closures capture values from previous calls?

孤街醉人 提交于 2019-12-18 22:31:14

问题


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

Isn't 'Line A' called each time we call counter1() ? meaning that var n = 0 should be called every time...

Why is that the counter returns different values? Shouldn't they always be returning '1' ?


回答1:


You've called makeCounter() once. That creates your new closure, and assigns it to counter1. This closure closes over the mutable var n, and will remain captured as long as this closure exists.

Calling counter1() will execute it, but it retains the same captured n, and mutates it. This particular "adder" will ALWAYS capture this same n, so long as it exists..

To get the behavior you're suggesting, you need to make new closures which capture new instances of 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

Now both counter1 and counter2 each have their own separate instances of n.




回答2:


Obviously, Line A isn't being called each time counter1 is called.

The sequence of events is:

  • makeCounter is called, which declares and initializes n (Line A), defines adder, and returns adder in a context that includes n already having been defined and initialized to 1.

  • It is this function that was just returned that is assigned to counter1. Because the Line A is not part of that function (adder/counter1), it does not get executed when that function is called.

  • Each call to counter1 is executed in that same context, which is why n retains its value across calls: they are all accessing the same n.



来源:https://stackoverflow.com/questions/37839020/how-do-closures-capture-values-from-previous-calls

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!