Context
I have a Generic Swift Class
containing a component Property
of the Generic Type
.
A few other Variables
with different Data Types
are passed through the Initializer
, however, all of them are conforming to the Generic Protocol
.
However, I get the following Compiler Error
in Line 11
:
'ComponentA' is not convertible to 'C'
Code
protocol Component { ... }
struct ComponentA: Component { ... }
struct ComponentB: Component { ... }
class Main<C: Component> {
var component: C
init(componentA: ComponentA, componentB: ComponentB) {
// I am trying to check, whether componentA equals the Generic Data Type and assign it to the component Property if true.
if case let safeComponent = componentA as C {
self.component = safeComponent
}
}
}
Question
How can I achieve my goal of checking whether a Data Type
equals the Generic Data Type
and assign it to the component Property
if true?
CodePudding user response:
You need to Check for componentA compatibility with C. For example :
protocol Component {
var name: String {get}
}
struct ComponentNil: Component {
var name: String
}
struct ComponentA: Component {
var name: String
var a: Int
}
struct ComponentB: Component {
var name: String
var b: Int
}
class Main<C: Component> {
var component: C
init(componentA: ComponentA, componentB: ComponentB) {
// Check that componentA is compatible with type C
if let safeComponent = componentA as? C {
self.component = safeComponent
} else {
// force componentB to be of type C
self.component = componentB as! C
// not that this may throw an error
}
}
}
CodePudding user response:
You have at least 3 possible approaches. All deal with the possibility that componentA
can not be cast to C
protocol Component { }
struct ComponentA: Component { }
struct ComponentB: Component { }
// optional `component`
class Main1<C: Component> {
var component: C?
init?(componentA: ComponentA, componentB: ComponentB) {
if let safeComponent = componentA as? C {
self.component = safeComponent
}
}
}
// init throws when precondtions not met
class Main2<C: Component> {
enum Errors: Error {
case preconditionsNotSatisfied
}
var component: C
init(componentA: ComponentA, componentB: ComponentB) throws {
if let safeComponent = componentA as? C {
self.component = safeComponent
} else {
throw Errors.preconditionsNotSatisfied
}
}
}
// init can return nil
class Main3<C: Component> {
var component: C
init?(componentA: ComponentA, componentB: ComponentB) {
if let safeComponent = componentA as? C {
self.component = safeComponent
} else {
return nil
}
}
}