I am trying to implement the Equatable protocol for a protocol based on the left' and right's operand identity. I other words: How do I implement the Equatable protocol for a protocol to determine if two instances that implement this protocol (in my case iNetworkSubscriber
) are identical (same object reference). Like that (error message is include in the code below):
protocol iNetworkSubscriber : Equatable {
func onMessage(_ packet: NetworkPacket)
}
func ==(lhs: iNetworkSubscriber, rhs: iNetworkSubscriber) -> Bool { // <- Protocol 'iNetworkSubscriber' can only be used as a generic constraint because it has Self or associated type requirements
return ObjectIdentifier(lhs) == ObjectIdentifier(rhs) // <- Cannot invoke initializer for type 'ObjectIdentifier' with an argument list of type '(iNetworkSubscriber)'
}
... and I also tried it with the identity operator itself:
func ==(lhs: iNetworkSubscriber, rhs: iNetworkSubscriber) -> Bool { // <- Protocol 'iNetworkSubscriber' can only be used as a generic constraint because it has Self or associated type requirements
return lhs === rhs // <- Binary operator '===' cannot be applied to two 'iNetworkSubscriber' operands
}
Somebody an idea how to solve this issue?
To adopt the Equatable protocol, implement the equal-to operator ( == ) as a static method of your type. The standard library provides an implementation for the not-equal-to operator ( != ) for any Equatable type, which calls the custom == function and negates its result.
In Swift, an Equatable is a protocol that allows two objects to be compared using the == operator. The hashValue is used to compare two instances. To use the hashValue , we first have to conform (associate) the type (struct, class, etc) to Hashable property.
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 ( != ). Most basic types in the Swift standard library conform to Equatable .
In Swift, there's the Equatable protocol, which explicitly defines the semantics of equality and inequality in a manner entirely separate from the question of identity. There's also the Comparable protocol, which builds on Equatable to refine inequality semantics to creating an ordering of values.
There are two problems here. The first is that you can't use ObjectIdentifier
on value types. So you must declare this protocol to require reference (class) types:
protocol NetworkSubscriber : class, Equatable {
func onMessage(_ packet: NetworkPacket)
}
(Please do not add a lowercase i
to the beginning of protocols. This is confusing in several ways in Swift.)
Then, you cannot use this protocol as a type. It describes a type (because it relies on Self
via Equatable
). So functions that accept it must be generic.
func ==<T: NetworkSubscriber>(lhs: T, rhs: T) -> Bool {
return ObjectIdentifier(lhs) == ObjectIdentifier(rhs)
}
Given that NetworkSubscriber
must be a class, you should ask very carefully whether you should be using inheritance here rather than a protocol. Protocols with associated types are very complex to use, and mixing classes and protocols creates even more complexity. Class inheritance is much simpler if you're already using classes.
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