Skip to content

Instantly share code, notes, and snippets.

@algal
Created November 10, 2015 00:09
Show Gist options
  • Save algal/4337376c7796d6c80322 to your computer and use it in GitHub Desktop.
Save algal/4337376c7796d6c80322 to your computer and use it in GitHub Desktop.
Gist trying to understand if Swift prevents capturing self in an initializer of a value type
// known confusing on Swift 2.1, Xcode 7.1
import Foundation
public class InnerMutator {
var f:(() -> Void)?
}
public struct MutableValue
{
let innerMutator:InnerMutator
var counter:Int = 0
public mutating func increment() {
print("ENTRY: increment")
self.counter = self.counter + 1
print("EXIT: increment")
}
init() {
self.innerMutator = InnerMutator()
// all of self's properties are now initialized
self.innerMutator.f = {
print("ENTRY: closure")
self.increment()
print("EXIT: closure")
}
}
}
var c = MutableValue()
c.counter // => 0 as expected
c.increment() // logging indicated increment() is called
c.counter // => 1 as expected
c.innerMutator.f?() // logging indicated increment() is called
c.counter // => 1, instead of 2. WWHAT?
/*
What's puzzling here is that increment is being called, but there is no indication
that any instance has been incremented.
Is there a prohibition or a bug relating to capturing self in an initializer?
Or is the capture of self capturing-by-value instead of capturing-by-reference, in
violation of the usual Swift rule that all capturing captures by reference?
*/
c.innerMutator.f = { c.increment() }
c.innerMutator.f?()
c.counter
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment