O que significa "Protocolo ... só pode ser usado como uma restrição genérica porque possui requisitos de Tipo próprio ou associado"?


123

Estou tentando criar um dicionário (na verdade um HashSet ) codificado em um protocolo personalizado no Swift, mas está me dando o erro no título:

O protocolo 'myProtocol' só pode ser usado como uma restrição genérica porque possui requisitos de tipo Próprio ou associado

e não posso fazer cara nem coroa disso.

protocol Observing: Hashable { }

var observers = HashSet<Observing>()


@jtbandes Isso não é duplicado. Estou perguntando o que realmente significa a mensagem de erro. O que é um "requisito de tipo próprio ou associado"?
devios1

Respostas:


90

O protocolo Observingherda do protocolo Hashable, que por sua vez herda do protocolo Equatable. O protocolo Equatabletem o seguinte requisito:

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

E um protocolo que contém Selfalgum lugar dentro dele não pode ser usado em qualquer lugar, exceto em uma restrição de tipo.

Aqui está uma pergunta semelhante.


7
... porque o compilador deve garantir que seja do mesmo tipo em ambos os lados, mas o protocolo apenas garante que ele atenda ao contrato. Entendo. Ainda assim, parece que isso Equatablenão deve implicar necessariamente, Equatablepois não é estritamente necessário gerar um código hash.
devios1

4
Ah, não, espere, porque Dictionaryprecisa saber se um determinado objeto é realmente a chave correta, porque é possível que dois objetos diferentes gerem o mesmo código de hash. Hmm, isso é um pouco complicado. Então, o problema aqui é realmente com Equatable.
devios1

4
Olhada 00:56 no grande apresentação por Alexis Gallagher intitulado: Protocolos com Tipos Associados e como eles ficaram assim (talvez) youtu.be/XWoNjiSPqI8
finneycanhelp

@finneycanhelp Obrigado por este 👍👍. Ótimo vídeo!
devios1

11

Para resolver isso, você pode usar genéricos. Considere este exemplo:

class GenericClass<T: Observing> {
   var observers = HashSet<T>()
}
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.