I have the the below Protocol
:
protocol Cacheable { //....// func identifier() -> String }
Can I make Cacheable
implements Equatable ?
when I do the following:
extension Cacheable: Equatable {} func ==(lhs:Cacheable,rhs:Cacheable) -> Bool { return lhs.identifier() == rhs.identifier() }
I got this error message : Extension of protocol Cacheable
cannot have an inheritance clause
Overview. Types that conform to the Equatable protocol can be compared for equality using the equal-to operator ( == ) or inequality using the not-equal-to operator ( != ).
Swift 4.1 update: With the introduction of conditional conformance in Swift 4.1, Array now conforms to Equatable , so the issue should be resolved without the need to resort to any workarounds.
Since Swift. Void is not Equatable , Box<Void> is not Equatable .
It is another protocol that is inherited from equatable, by conforming to which you will get a hash value of integer type for a particular instance, any type that conforms to Hashable must also conform to Equatable.
Cacheable
s of the same type to be compareprotocol Cacheable: Equatable { //....// func identifier() -> String } func ==<T : Cacheable>(lhs: T, rhs: T) -> Bool { return lhs.identifier() == rhs.identifier() }
This is the simplest solution.
You can only compare two Cacheable
objects of the same type. This means that code below will fail and in order to fix it you need to make Animal
conform to Cacheable
:
class Animal { } class Dog: Animal,Cacheable { func identifier() -> String { return "object" } } class Cat: Animal,Cacheable { func identifier() -> String { return "object" } } let a = Dog() let b = Cat() a == b //such comparison is not allowed
Cacheable
s of any type to be comparedprotocol Cacheable:Equatable { //....// func identifier() -> String } func ==<T:Cacheable>(lhs: T, rhs: T) -> Bool { return lhs.identifier() == rhs.identifier() } func !=<T:Cacheable>(lhs: T, rhs: T) -> Bool { return lhs.identifier() != rhs.identifier() } func ==<T:Cacheable, U:Cacheable>(lhs: T, rhs: U) -> Bool { return lhs.identifier() == rhs.identifier() } func !=<T:Cacheable, U:Cacheable>(lhs: T, rhs: U) -> Bool { return lhs.identifier() != rhs.identifier() }
Removes limitations described above for solution 1. Now you can easily compare Dog
and Cat
.
==
functions is not sufficient - this might be a bug with a compiler. Anyway, you have to provide the implementation for both ==
and !=
.Equatable
protocol Cacheable { //....// func identifier() -> String } func ==(lhs: Cacheable, rhs: Cacheable) -> Bool { return lhs.identifier() == rhs.identifier() } func !=(lhs: Cacheable, rhs: Cacheable) -> Bool { return lhs.identifier() != rhs.identifier() }
You can use Cacheable
as type without needing any generics. This introduces a whole new range of possibilities. For example:
let c:[Cacheable] = [Dog(),RaceCar()] c[0] == c[1] c[0] != c[1]
With solutions 1 and 2 such code would fail and you would have to use generics in your classes. However, with the latest implementation Cacheable
is treated as a type, so you are allowed to declare an array of type [Cacheable]
.
You no longer declare conformance to Equatable
so any functions which accept Equatable
parameters will not accept Cacheable
. Obviously, apart from ==
and !=
as we declared them for Cacheable
s.
If this is not a problem in your code I would actually prefer this solution. Being able to treat protocol as a type is super useful in many cases.
Try.
extension Equatable where Self : Cacheable { }
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