Co oznacza „Protokół… może być używany tylko jako ogólne ograniczenie, ponieważ ma własne lub związane z nim wymagania”?

123

Próbuję utworzyć słownik (właściwie HashSet ) z kluczem niestandardowym w Swift, ale w tytule pojawia się błąd:

Protokół „myProtocol” może być używany tylko jako ograniczenie ogólne, ponieważ ma wymagania typu Self lub powiązane

i nie mogę zrobić z tego głów ani ogonów.

protocol Observing: Hashable { }

var observers = HashSet<Observing>()
devios1
źródło
@jtbandes To nie jest duplikat. Pytam, co właściwie oznacza komunikat o błędzie. Co to jest „własny lub powiązany typ wymagania”?
devios1

Odpowiedzi:

90

Protokół Observingdziedziczy po protokole Hashable, który z kolei dziedziczy po protokole Equatable. Protokół Equatablema następujące wymagania:

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

A protokołu, który zawiera Selfgdzieś w środku, nie można używać nigdzie, z wyjątkiem ograniczenia typu.

Oto podobne pytanie.

newacct
źródło
7
... ponieważ kompilator musi upewnić się, że jest tego samego typu po obu stronach, ale protokół zapewnia tylko zgodność z umową. Widzę. Jednak wydaje się, że Equatablenie powinno to koniecznie oznaczać, Equatableponieważ nie jest to absolutnie konieczne do wygenerowania kodu skrótu.
devios1
4
Och, nie czekaj, to robi, ponieważ Dictionarymusi być w stanie wiedzieć, czy dany obiekt jest rzeczywiście prawidłowym kluczem, ponieważ dwa różne obiekty mogą wygenerować ten sam kod skrótu. Hmm, to trochę skomplikowane. Więc problem jest naprawdę z Equatable.
devios1
4
Spójrz na 0:56 do wielkiej prezentacji Alexis Gallagher zatytułowanym: Protokoły z typami towarzyszących i jak dostali w ten sposób (być może) youtu.be/XWoNjiSPqI8
finneycanhelp
@finneycanhelp Dzięki za to 👍👍. Świetny film!
devios1
11

Aby rozwiązać ten problem, możesz użyć leków generycznych. Rozważmy ten przykład:

class GenericClass<T: Observing> {
   var observers = HashSet<T>()
}
ph1lb4
źródło