Digamos que eu tenho estes protocolos:
protocol SomeProtocol {
}
protocol SomeOtherProtocol {
}
Agora, se eu quiser uma função que aceite um tipo genérico, mas esse tipo deva estar em conformidade, SomeProtocol
eu poderia fazer:
func someFunc<T: SomeProtocol>(arg: T) {
// do stuff
}
Mas existe uma maneira de adicionar uma restrição de tipo para vários protocolos?
func bothFunc<T: SomeProtocol | SomeOtherProtocol>(arg: T) {
}
Coisas semelhantes usam vírgulas, mas, neste caso, iniciariam a declaração de um tipo diferente. Aqui está o que eu tentei.
<T: SomeProtocol | SomeOtherProtocol>
<T: SomeProtocol , SomeOtherProtocol>
<T: SomeProtocol : SomeOtherProtocol>
Respostas:
Você pode usar uma cláusula where que permite especificar quantos requisitos você deseja (todos os quais devem ser atendidos) separados por vírgulas
Swift 2:
Swift 3 e 4:
ou a cláusula where mais poderosa:
É claro que você pode usar a composição do protocolo (por exemplo,
protocol<SomeProtocol, SomeOtherProtocol>
), mas é um pouco menos flexível.Usar
where
permite lidar com casos em que vários tipos estão envolvidos.Você ainda pode compor protocolos para reutilização em vários locais ou apenas atribuir um nome significativo ao protocolo composto.
Swift 5:
Isso parece mais natural, pois os protocolos estão próximos ao argumento.
fonte
<T where T:SomeStruct, T:AnotherStruct>
? Para classes, o compilador parece interpretar isso como dizendo "T é uma subclasse de ambos" e, para estruturas, apenas reclama isso"Type 'T' constrained to non-protocol type"
.where
cláusula para tipo / outro uso adicional, por exemplo,func someFunc<U, T: protocol<SomeProtocol, SomeOtherProtocol> where T.SubType == U>(arg: T, arg2: U) { ... }
para tipealiasSubType
em, por exemploSomeProtocol
.Você tem duas possibilidades:
Você usa uma cláusula where conforme indicado na resposta de Jiaaro:
Você usa um tipo de composição de protocolo :
fonte
typealias
. Obrigado!A evolução para o Swift 3.0 traz algumas mudanças. Nossas duas opções agora parecem um pouco diferentes.
Usando uma
where
cláusula no Swift 3.0:A
where
cláusula agora foi movida para o final de uma assinatura de função para melhorar a legibilidade. Portanto, a herança de vários protocolos agora se parece com isso:Usando a
protocol<>
construção no Swift 3.0:A composição usando a
protocol<>
construção está sendo preterida. O anteriorprotocol<SomeProtocol, SomeOtherProtocol>
agora se parece com isso:Referências.
Mais informações sobre as alterações
where
estão aqui: https://github.com/apple/swift-evolution/blob/master/proposals/0081-move-where-expression.mdE, mais sobre as mudanças para a construção do protocolo <> estão aqui: https://github.com/apple/swift-evolution/blob/master/proposals/0095-any-as-existential.md
fonte
O Swift 3 oferece até três maneiras diferentes de declarar sua função.
1. Usando
&
operador2.
where
Cláusula Using3. Usando
where
cláusula e&
operadorObserve também que você pode usar
typealias
para reduzir sua declaração de função.fonte