Consider a property wrapper that has a default and an override value, where wrappedValue will return default unless override is specified, in which case it will return override instead:
@propertyWrapper
struct Foo<B> {
typealias Bar = B
/// Default value to use unless `override` is specified.
var `default`: Bar
/// A value to use instead of the default.
var override: Bar?
init(override: Bar? = nil, default: Bar) {
self.default = `default`
guard let override = override as? Bar else {
self.override = nil
return
}
self.override = override
}
var wrappedValue: Bar {
guard let override = override as? Bar else {
return `default`
}
return override
}
}
Now when I use @Foo to wrap an optional parameter, it never returns the default value even when I don't specify an override:
struct Qux {
@Foo(default: 42) var optionalFoo: Int?
@Foo(default: 42) var nonOptionalFoo: Int
}
let qux = Qux()
print("\(qux.optionalFoo)") // always prints "nil"!
print("\(qux.nonOptionalFoo)") // prints 42 as expected
To me this seems like a bug or issue with Swift.
Since no override is specified in @Foo(default: 42) var optionalFoo: Int?, therefore optionalFoo should be 42, not "nil". It should only be nil if the wrapper is specified like @Foo(override: nil, default: 42). But of course "nil" has to be the default value of "override" for times when no override is specified, so it's like a catch-22.
What is the solution here? How can I represent override so that in case the generic parameter Foo.Bar is actually an optional, then I can make override be able to either be nil (no override) or Optional<Bar>.none (override the default and use nil instead)?