lolgear
(Dmitry Lobanov)
1
It is a bit complicated for myself to read documentation about capturing lists and closures.
For example, neither Closures nor capturing lists sections contains a capturing list with assignment.
Consider following complex example and answer one question: What will be printed to console?
enum ClosuresScope {
class ExampleClass: CustomStringConvertible {
var item: Int = 0
func update(item: Int) {
self.item += item
}
var description: String {
return "self -> \(self.item)"
}
}
struct ExampleStruct {
var item: Int = 0
mutating func update(item: Int) {
self.item += item
}
}
class CapturingAndBlockAttribute {
func example() {
let classItem = ExampleClass()
var structItem = ExampleStruct()
let closure: () -> (Int) = {
[unowned internalClass = classItem, internalStruct = structItem] in
classItem.update(item: 3)
internalClass.update(item: 20)
internalStruct.update(item: 5)
structItem.update(item: 10)
return classItem.item
}
classItem.update(item: 5)
structItem.update(item: 5)
_ = closure()
print("classItem: \(classItem) structItem: \(structItem)")
}
}
}
krilnon
(Kyle Murray)
2
For anywhere you'd like to see improved documentation about language-level constructs like capture lists, the best place to file a bug is https://bugreporter.apple.com
You might find the Capture Lists section in the language reference useful.
If you run the example method:
ClosuresScope.CapturingAndBlockAttribute().example()
You'll get a compiler error about mutating a closure parameter from this line:
internalStruct.update(item: 5)
Is your broader question about the value vs. reference semantics of capture lists? There's some discussion and examples in the section I linked earlier:
The a in the inner scope is initialized with the value of the a in the outer scope when the closure is created, but their values are not connected in any special way. This means that a change to the value of a in the outer scope does not affect the value of a in the inner scope, nor does a change to a inside the closure affect the value of a outside the closure. In contrast, there is only one variable named b —the b in the outer scope—so changes from inside or outside the closure are visible in both places.
This distinction is not visible when the captured variable’s type has reference semantics.
1 Like