J'ai le Protocol
ci-dessous:
protocol Cacheable {
//....//
func identifier() -> String
}
Puis-je rendre Cacheable
implements Equatable?
quand je fais ce qui suit:
extension Cacheable: Equatable {}
func ==(lhs:Cacheable,rhs:Cacheable) -> Bool {
return lhs.identifier() == rhs.identifier()
}
J'ai reçu ce message d'erreur: L'extension du protocole Cacheable
ne peut pas avoir de clause d'héritage
Cacheable
du même typeprotocol Cacheable: Equatable {
//....//
func identifier() -> String
}
func ==<T : Cacheable>(lhs: T, rhs: T) -> Bool {
return lhs.identifier() == rhs.identifier()
}
C'est la solution la plus simple.
Vous ne pouvez comparer que deux objets Cacheable
du même type. Cela signifie que le code ci-dessous échouera et pour le corriger, vous devez rendre Animal
conforme à 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 de tout typeprotocol 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()
}
Supprime les limitations décrites ci-dessus pour la solution 1. Vous pouvez désormais comparer facilement Dog
et Cat
.
==
les fonctions ne sont pas suffisantes - cela pourrait être un bogue avec un compilateur. Quoi qu'il en soit, vous devez fournir l'implémentation à la fois ==
et !=
.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()
}
Vous pouvez utiliser Cacheable
comme type sans avoir besoin de génériques. Cela introduit une toute nouvelle gamme de possibilités. Par exemple:
let c:[Cacheable] = [Dog(),RaceCar()]
c[0] == c[1]
c[0] != c[1]
Avec les solutions 1 et 2, ce code échouerait et vous devriez utiliser des génériques dans vos classes. Cependant, avec la dernière implémentation, Cacheable
est traité comme un type, vous êtes donc autorisé à déclarer un tableau de type [Cacheable]
.
Vous ne déclarez plus la conformité à Equatable
donc toutes les fonctions qui acceptent les paramètres Equatable
n'accepteront pas Cacheable
. De toute évidence, à part ==
et !=
comme nous les avons déclarés pour Cacheable
s.
Si ce n'est pas un problème dans votre code, je préférerais en fait cette solution. Être capable de traiter le protocole comme un type est super utile dans de nombreux cas.
Essayer.
extension Equatable where Self : Cacheable {
}