¿Qué significa "Protocolo ... solo puede usarse como una restricción genérica porque tiene requisitos de tipo Self o asociados"?

123

Estoy tratando de crear un Diccionario (en realidad un HashSet ) codificado en un protocolo personalizado en Swift, pero me está dando el error en el título:

El protocolo 'myProtocol' solo se puede usar como una restricción genérica porque tiene requisitos de tipo Self o asociados

y no puedo hacer cara ni cruz.

protocol Observing: Hashable { }

var observers = HashSet<Observing>()
devios1
fuente
@jtbandes Eso no es un duplicado. Estoy preguntando qué significa realmente el mensaje de error. ¿Qué es un "requisito de tipo propio o asociado"?
devios1

Respuestas:

90

El protocolo Observinghereda del protocolo Hashable, que a su vez hereda del protocolo Equatable. El protocolo Equatabletiene el siguiente requisito:

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

Y un protocolo que contiene Selfalgún lugar dentro de él no se puede usar en ningún lugar excepto en una restricción de tipo.

Aquí hay una pregunta similar.

newacct
fuente
77
... porque el compilador debe asegurarse de que sea del mismo tipo en ambos lados, pero el protocolo solo garantiza que cumpla con el contrato. Veo. Aún así, parece que Equatableno debería implicar necesariamente, Equatableya que eso no es estrictamente necesario para generar un código hash.
devios1
44
Oh, no, espere, porque Dictionarynecesita poder saber si un objeto dado es realmente la clave correcta, porque es posible que dos objetos diferentes generen el mismo código hash. Hmm, eso es un poco complicado. Entonces el problema aquí es realmente con Equatable.
devios1
44
Mire 0:56 en la gran presentación de Alexis Gallagher titulada: Protocolos con tipos asociados y cómo llegaron de esa manera (tal vez) youtu.be/XWoNjiSPqI8
finneycanhelp
@finneycanhelp Gracias por esto 👍👍. ¡Gran video!
devios1
11

Para resolver esto, podrías usar genéricos. Considere este ejemplo:

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