I have a protocol P that returns a copy of the object:
protocol P {
func copy() -> Self
}
and a class C that implements P:
class C : P {
func copy() -> Self {
return C()
}
}
However, whether I put the return value as Self
I get the following error:
Cannot convert return expression of type 'C' to return type 'Self'
I also tried returning C
.
class C : P {
func copy() -> C {
return C()
}
}
That resulted in the following error:
Method 'copy()' in non-final class 'C' must return
Self
to conform to protocol 'P'
Nothing works except for the case where I prefix class C
with final
ie do:
final class C : P {
func copy() -> C {
return C()
}
}
However if I want to subclass C then nothing would work. Is there any way around this?
Just throwing my hat into the ring here. We needed a protocol that returned an optional of the type the protocol was applied on. We also wanted the override to explicitly return the type, not just Self.
The trick is rather than using 'Self' as the return type, you instead define an associated type which you set equal to Self, then use that associated type.
Here's the old way, using Self...
Here's the new way using the associated type. Note the return type is explicit now, not 'Self'.
Following on Rob's suggestion, this could be made more generic with associated types. I've changed the example a bit to demonstrate the benefits of the approach.