Disons que j'ai ces protocoles:
protocol SomeProtocol {
}
protocol SomeOtherProtocol {
}
Maintenant, si je veux une fonction qui prend un type générique, mais que ce type doit être conforme, SomeProtocol
je pourrais faire:
func someFunc<T: SomeProtocol>(arg: T) {
// do stuff
}
Mais existe-t-il un moyen d'ajouter une contrainte de type pour plusieurs protocoles?
func bothFunc<T: SomeProtocol | SomeOtherProtocol>(arg: T) {
}
Des choses similaires utilisent des virgules, mais dans ce cas, cela commencerait la déclaration d'un type différent. Voici ce que j'ai essayé.
<T: SomeProtocol | SomeOtherProtocol>
<T: SomeProtocol , SomeOtherProtocol>
<T: SomeProtocol : SomeOtherProtocol>
Réponses:
Vous pouvez utiliser une clause where qui vous permet de spécifier autant d'exigences que vous le souhaitez (qui doivent toutes être remplies) séparées par des virgules
Swift 2:
Swift 3 et 4:
ou la clause where la plus puissante:
Vous pouvez bien sûr utiliser la composition de protocole (par exemple,
protocol<SomeProtocol, SomeOtherProtocol>
), mais c'est un peu moins flexible.L'utilisation
where
vous permet de traiter les cas où plusieurs types sont impliqués.Vous voudrez peut-être toujours composer des protocoles pour les réutiliser à plusieurs endroits, ou simplement donner au protocole composé un nom significatif.
Swift 5:
Cela semble plus naturel car les protocoles sont à côté de l'argument.
la source
<T where T:SomeStruct, T:AnotherStruct>
? Pour les classes, le compilateur semble interpréter cela comme disant "T est une sous-classe des deux", et pour les structures, il se plaint simplement de cela"Type 'T' constrained to non-protocol type"
.where
clause pour un type supplémentaire / une autre utilisation, par exemplefunc someFunc<U, T: protocol<SomeProtocol, SomeOtherProtocol> where T.SubType == U>(arg: T, arg2: U) { ... }
pour les typealiasSubType
dans par exempleSomeProtocol
.Vous avez deux possibilités:
Vous utilisez une clause where comme indiqué dans la réponse de Jiaaro:
Vous utilisez un type de composition de protocole :
la source
typealias
. Merci!L'évolution vers Swift 3.0 apporte quelques changements. Nos deux choix sont maintenant un peu différents.
Utilisation d'une
where
clause dans Swift 3.0:La
where
clause est maintenant déplacée à la fin d'une signature de fonction pour améliorer la lisibilité. L'héritage de plusieurs protocoles ressemble maintenant à ceci:Utilisation de la
protocol<>
construction dans Swift 3.0:La composition utilisant la
protocol<>
construction est obsolète. Le plus tôtprotocol<SomeProtocol, SomeOtherProtocol>
ressemble maintenant à ceci:Références.
Plus d'informations sur les changements pour
where
sont ici: https://github.com/apple/swift-evolution/blob/master/proposals/0081-move-where-expression.mdEt, plus sur les changements pour la construction de protocole <> sont ici: https://github.com/apple/swift-evolution/blob/master/proposals/0095-any-as-existential.md
la source
Swift 3 propose jusqu'à 3 façons différentes de déclarer votre fonction.
1. Utilisation de l'
&
opérateur2. Utilisation de la
where
clause3. Utilisation de la
where
clause et de l'&
opérateurNotez également que vous pouvez utiliser
typealias
pour raccourcir votre déclaration de fonction.la source