The problem is that abstract types in Swift don't necessarily conform to themselves – therefore you cannot use a SomeProtocol
typed thing as a concrete typed thing that conforms to SomeProtocol
(which is what your add1
generic function expects as an argument).
The simplest solution in your case therefore is just to use the generic variable
argument, rather than the variable
property, as because it's a generic, it's typed as a concrete thing that conforms to SomeProtocol
, which can therefore be passed into your add1
function:
init<A: SomeProtocol>(variable: A) {
self.variable = variable
add1(variable)
}
However in order to prevent these kind of issues later down the line, you may want to consider making your class generic, assuming that your variable
property should be of constant type throughout the lifetime of a given Thing1
instance:
class Thing1<A:SomeProtocol> {
let variable: A
init(variable: A) {
self.variable = variable
add1(variable)
}
func add1(stuff: A) {
let thing = Thing2()
thing.add2(stuff)
}
}
Or, you could refactor your code to use the abstract type SomeProtocol
, which will allow you to work with any type that conforms to SomeProtocol
(e.g allowing you to mix different Thing1
instances with different variable
types in an array):
class Thing1 {
let variable: SomeProtocol
init(variable: SomeProtocol) {
self.variable = variable
add1(variable)
}
func add1(stuff: SomeProtocol) {
let thing = Thing2()
thing.add2(stuff)
}
}
class Thing2 {
func add2(stuff: SomeProtocol) {
}
}
Although you should always be aware of the extra costs that come with using abstract types, see this great WWDC talk for more info.