Reputation: 1269
In Capturing Values section of swift documentation:
... It does this by capturing a reference to runningTotal and amount from the surrounding function and using them within its own function body. ...
and
If you create a second incrementer, it will have its own stored reference to a new, separate runningTotal variable.
So I try the following testing and get a conclusion that since each incrementer made by the makeIncrementer(forIncrementer:)
has its own runningTotal
and the value of runningTotal
is remembered by each incrementer, what values-capturing does is equivalent to creating some static variable(s) for a closure. But I'm not sure whether my statement is correct.
func makeIncrementer(forIncrement amount: Int) -> () -> Int {
var runningTotal = 0
func incrementer() -> Int {
runningTotal += amount
return runningTotal
}
return incrementer
}
let by10Incrementer = makeIncrementer(forIncrement: 10)
let by20Incrementer = makeIncrementer(forIncrement: 20)
for i in 0..<5 {
print(by10Incrementer())
}
print("---")
for j in 0..<5 {
print(by20Incrementer())
}
output:
10
20
30
40
50
---
20
40
60
80
100
I originally thought that the output of by20Incrementer()
would start from 50, but it starts from 0. So the runningTotal
of each incrementer refers to different one.
Upvotes: 2
Views: 823
Reputation: 726479
Captures do not become static in a closure, in the sense that each instance of the closure gets its own copy of the variable.
I originally thought that the output of
by20Incrementer()
would start from 50, but it starts from 0
It starts from the value of runningTotal
at the time the closure is created, which is always zero. No matter how many times you increment runningTotal
in by10Incrementer
, it wouldn't change the value of runningTotal
captured in by20Incrementer
, because it is a different instance with its own capture of runningTotal
.
Effectively, runningTotal
becomes a var
on the object that represents the closure. Swift syntax makes this capture implicit, but internally the variable is there.
Upvotes: 4