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)?