Predict the output when a captured variable is mutated after capture
Read the snippet. One closure captures x in a capture list [x]; another captures x with no capture list. x is then mutated before either closure runs.
var x = 1
let byValue = { [x] in print(x) }
let byReference = { print(x) }
x = 99
byValue()
byReference()
What does each call print, and why? Explain the difference the capture list makes. Determine the output.
byValue() prints 1; byReference() prints 99. A capture list [x] copies x by value when the closure is created, so a later mutation of x is invisible to it. Without a capture list the closure captures the variable by reference and reads its current value at call time, 99.
- ✗Thinking a capture list is only a style hint with no runtime effect
- ✗Believing a bare capture snapshots the value at creation time
- ✗Assuming both closures always print the same value
- →How does
[weak self]differ from[x]in what it captures? - →Why does reference capture read the value at call time, not creation?
Output: 1, then 99.
var x = 1
let byValue = { [x] in print(x) } // copies x = 1 now
let byReference = { print(x) } // reads x at call time
x = 99
byValue() // 1 — value frozen at creation
byReference() // 99 — reads the current x
A capture list [x] evaluates x and stores a copy at the moment the closure is created, so the later x = 99 does not affect it. Without a capture list the closure holds the variable itself and reads its value at call time, after the assignment — hence 99.