Que signifie «Protocole… ne peut être utilisé que comme contrainte générique parce qu'il a des exigences de type Self ou associé»?

123

J'essaie de créer un dictionnaire (en fait un HashSet ) basé sur un protocole personnalisé dans Swift, mais cela me donne l'erreur dans le titre:

Le protocole 'myProtocol' ne peut être utilisé que comme contrainte générique car il a des exigences de type Self ou associées

et je ne peux pas en faire la tête ni la queue.

protocol Observing: Hashable { }

var observers = HashSet<Observing>()
devios1
la source
@jtbandes Ce n'est pas un doublon. Je demande ce que signifie réellement le message d'erreur. Qu'est-ce qu'une «exigence de type propre ou associée»?
devios1

Réponses:

90

Le protocole Observinghérite du protocole Hashable, qui à son tour hérite du protocole Equatable. Le protocole Equatablea l'exigence suivante:

func ==(lhs: Self, rhs: Self) -> Bool

Et un protocole qui contient Selfquelque part à l'intérieur ne peut être utilisé nulle part sauf dans une contrainte de type.

Voici une question similaire.

newacct
la source
7
... parce que le compilateur doit s'assurer qu'il est du même type de chaque côté, mais le protocole garantit seulement qu'il respecte le contrat. Je vois. Pourtant, il semble que cela Equatablene devrait pas nécessairement impliquer Equatablepuisque ce n'est pas strictement nécessaire pour générer un code de hachage.
devios1
4
Oh non, attendez, car il Dictionaryfaut pouvoir savoir si un objet donné est effectivement la bonne clé, car il est possible que deux objets différents génèrent le même code de hachage. Hmm, c'est un peu délicat. Le problème ici est donc vraiment avec Equatable.
devios1
4
Regardez 0:56 dans la grande présentation d'Alexis Gallagher intitulée: Protocoles avec les types associés et comment ils sont arrivés de cette façon (peut-être) youtu.be/XWoNjiSPqI8
finneycanhelp
@finneycanhelp Merci pour cela 👍👍. Bonne vidéo!
devios1
11

Pour résoudre ce problème, vous pouvez utiliser des génériques. Prenons cet exemple:

class GenericClass<T: Observing> {
   var observers = HashSet<T>()
}
ph1lb4
la source