I need a Swift property that -- if the value has not yet been set -- defaults to another value.
This can be implemented using backing-store private properties. For instance, for a property num
that should default to a global defaultNum
, it would work something like this:
var defaultNum = 1
class MyClass {
var num: Int {
get { _num ?? defaultNum }
set { _num = newValue }
}
private var _num: Int?
}
let c = MyClass()
print("initial \(c.num)") // == 1 ✅
// changing the default changes the value returned
defaultNum = 2
print("dynamic \(c.num)") // == 2 ✅
// once the property is set, returns the stored value
c.num = 5
print("base \(c.num)") // == 5 ✅
That works, but for a common pattern in our code, it's a lot of boilerplate for each such property.
Using Swift property wrappers, is it possible to do this more concisely?
What won't work
Note that, because we expect the default to be dynamic, static initializers will not work. For example:
var defaultNum = 1
class MyClass {
var num = defaultNum
}
var c = MyClass()
defaultNum = 2
print(c.num) // this == 1, we want the current value of defaultNum, which == 2