I have a generic type, and I would like to initialise it in different ways, depending on whether the actual type is Optional
or not.
struct Foo<Bar> {
var value: Bar
}
extension Foo {
init(data: Any) throws {
if let typedData: Bar = data as? Bar {
self.value = typedData
}
else {
throw NSError(domain: "", code: 0, userInfo: nil)
}
}
}
// (invalid restriction)
extension Foo where Bar: Optional<Bar> {
init(data: Any) throws {
if (data as? NSNull) == nil {
if let typedData: Bar = data as? Bar {
self.value = typedData
}
else {
throw NSError(domain: "", code: 0, userInfo: nil)
}
}
else {
self.value = nil
}
}
}
The idea being that I am initialising from some unknown data type which should either initialise correctly if the type corresponds, or throw an error otherwise, but where NSNull
corresponds to a nil
value if the type is Optional
.
let nonOptionalData: Any = Bar()
// should be successful
let foo1: Foo<Bar> = try Foo(data: nonOptionalData)
let nonOptionalIncorrectData: Any = NSNull()
// should throw an error
let foo2: Foo<Bar> = try Foo(data: nonOptionalIncorrectData)
let optionalData: Any = Bar()
// should be successful
let foo3: Foo<Bar?> = try Foo(data: optionalData)
let optionalIncorrectData: Any = Bob()
// should throw an error
let foo4: Foo<Bar?> = try Foo(data: optionalIncorrectData)
let optionalNullData: Any = NSNull()
// should be successful
let foo5: Foo<Bar?> = try Foo(data: optionalNullData)
Does anyone know if this is possible (the code above fails because we can't restrict the extension to the Optional
type), and if so, how it can be done?