Can I add protocol conformance to a protocol via a swift extension?
//Plain old protocol here protocol MyData { var myDataID: Int { get } }
I want to make the MyData
protocol equatable by default (just compare the ID)
extension MyData : Equatable { }
But I get this lovely error:
"Extension of protocol 'MyData' cannot have an inheritance clause"
The behavior i'm looking is BananaData conforming to Equatable (a protocol) because it implements the MyData protocol which can provide a default implementation of Equatable
//This is the method to implement Equatable func ==(lhs: MyData, rhs: MyData) -> Bool { return lhs.myDataID == rhs.myDataID } struct BananaData: MyData { var myDataID: Int = 1 } func checkEquatable(bananaOne: BananaData, bananaTwo: BananaData) { //This compiles, verifying that BananaData can be compared if bananaOne == bananaTwo { } //But BananaData is not convertible to Equatable, which is what I want let equatableBanana = bananaOne as Equatable //I don't get the additional operations added to Equatable (!=) if bananaOne != bananaTwo { } //Error }
Any type that satisfies the requirements of a protocol is said to conform to that protocol. In addition to specifying requirements that conforming types must implement, you can extend a protocol to implement some of these requirements or to implement additional functionality that conforming types can take advantage of.
A Swift protocol can inherit from other protocols, requiring conforming types to provide implementations for all the property and method requirements in the entire protocol hierarchy. A protocol can inherit from multiple protocols by listing the parent protocols in its declaration, separated by commas.
In Swift, protocols contain multiple abstract members. Classes, structs and enums can conform to multiple protocols and the conformance relationship can be established retroactively.
To create a protocol, use the protocol keyword followed by the name you want and defined by the curly braces. Protocols can be of 2 types: read-only/read-write. Read-only means you can only get the variable, but you cannot set it. Read-write means you can both set and get properties.
As the error message says: an extension of a protocol cannot have an inheritance clause. Instead, you could make MyData
protocol inherit from Equatable
in the original declaration.
protocol MyData: Equatable { var myDataID: Int { get } }
You could then extend add an implementation of ==
for types that conform to MyData
:
func == <T: MyData>(lhs: T, rhs: T) -> Bool { return lhs.myDataID == rhs.myDataID }
However, I would highly not recommend this! If you add more properties to conforming types, their properties won't be checked for equality. Take the example below:
struct SomeData: MyData { var myDataID: Int var myOtherData: String } let b1 = SomeData(myDataID: 1, myOtherData: "String1") let b2 = SomeData(myDataID: 1, myOtherData: "String2") b1 == b2 // true, although `myOtherData` properties aren't equal.
In the case above you'd need to override ==
for SomeData
for the correct result, thus making the ==
that accepts MyData
redundant.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With