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?
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.