Was bedeutet "Protokoll ... kann nur als generische Einschränkung verwendet werden, weil es Selbst- oder zugehörige Typanforderungen hat"?

123

Ich versuche, ein Wörterbuch (eigentlich ein HashSet ) zu erstellen, das auf einem benutzerdefinierten Protokoll in Swift verschlüsselt ist , aber es gibt mir den Fehler im Titel:

Das Protokoll 'myProtocol' kann nur als generische Einschränkung verwendet werden, da es Self- oder zugehörige Typanforderungen hat

und ich kann weder Kopf noch Zahl daraus machen.

protocol Observing: Hashable { }

var observers = HashSet<Observing>()
devios1
quelle
@jtbandes Das ist kein Duplikat. Ich frage, was die Fehlermeldung eigentlich bedeutet. Was ist eine "Selbst- oder zugehörige Typanforderung"?
Devios1

Antworten:

90

Das Protokoll Observingerbt vom Protokoll Hashable, das wiederum vom Protokoll erbt Equatable. Das Protokoll Equatablehat folgende Anforderung:

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

Und ein Protokoll, das Selfirgendwo darin enthalten ist, kann nur in einer Typbeschränkung verwendet werden.

Hier ist eine ähnliche Frage.

newacct
quelle
7
... weil der Compiler sicherstellen muss, dass es auf beiden Seiten der gleiche Typ ist, das Protokoll jedoch nur sicherstellt, dass er den Vertrag erfüllt. Aha. Dennoch scheint es Equatablenicht unbedingt zu implizieren, Equatableda dies nicht unbedingt erforderlich ist, um einen Hash-Code zu generieren.
Devios1
4
Oh nein, warten Sie, denn es Dictionarymuss möglich sein zu wissen, ob ein bestimmtes Objekt tatsächlich der richtige Schlüssel ist, da zwei verschiedene Objekte denselben Hash-Code generieren können. Hmm, das ist ein bisschen schwierig. Das Problem hier ist also wirklich mit Equatable.
Devios1
4
Schauen Sie sich 0:56 in der großartigen Präsentation von Alexis Gallagher mit dem Titel: Protokolle mit assoziierten Typen an und wie sie (vielleicht) auf diese Weise entstanden sind. Youtu.be/XWoNjiSPqI8
finneycanhelp
@ finneycanhelp Danke dafür 👍👍. Tolles Video!
Devios1
11

Um dies zu lösen, könnten Sie Generika verwenden. Betrachten Sie dieses Beispiel:

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