the - Múltiples restricciones de tipo en Swift
swift wikipedia (4)
La evolución a Swift 3.0 trae algunos cambios. Nuestras dos opciones ahora se ven un poco diferentes.
Usando una cláusula where
en Swift 3.0:
La cláusula where
ha movido al final de la firma de una función para mejorar la legibilidad. Así que la herencia de protocolos múltiples ahora se ve así:
func someFunc<T>(arg: T) where T:SomeProtocol, T:SomeOtherProtocol {
}
Usando la construcción de protocol<>
en Swift 3.0:
La composición que usa el protocol<>
constructo está en desuso. El protocol<SomeProtocol, SomeOtherProtocol>
anterior protocol<SomeProtocol, SomeOtherProtocol>
ahora se ve así:
func someFunc<T:SomeProtocol & SomeOtherProtocol>(arg: T) {
}
Referencias
Más información sobre los cambios para where
están aquí: https://github.com/apple/swift-evolution/blob/master/proposals/0081-move-where-expression.md
Y, más sobre los cambios para la construcción del protocolo <> están aquí: https://github.com/apple/swift-evolution/blob/master/proposals/0095-any-as-existential.md
Digamos que tengo estos protocolos:
protocol SomeProtocol {
}
protocol SomeOtherProtocol {
}
Ahora, si quiero una función que tome un tipo genérico, pero ese tipo debe ajustarse a SomeProtocol
, podría hacer lo siguiente:
func someFunc<T: SomeProtocol>(arg: T) {
// do stuff
}
Pero, ¿hay alguna manera de agregar una restricción de tipo para múltiples protocolos?
func bothFunc<T: SomeProtocol | SomeOtherProtocol>(arg: T) {
}
Cosas similares usan comas, pero en este caso, comenzaría la declaración de un tipo diferente. Esto es lo que he intentado.
<T: SomeProtocol | SomeOtherProtocol>
<T: SomeProtocol , SomeOtherProtocol>
<T: SomeProtocol : SomeOtherProtocol>
Puede usar una cláusula where que le permite especificar tantos requisitos como desee (todos los cuales deben cumplirse) separados por comas
Swift 2:
func someFunc<T where T:SomeProtocol, T:SomeOtherProtocol>(arg: T) {
// stuff
}
Swift 3 y 4:
func someFunc<T: SomeProtocol & SomeOtherProtocol>(arg: T) {
// stuff
}
o la cláusula where más poderosa:
func someFunc<T>(arg: T) where T:SomeProtocol, T:SomeOtherProtocol{
// stuff
}
Por supuesto, puede usar la composición del protocolo (por ejemplo, protocol<SomeProtocol, SomeOtherProtocol>
), pero es un poco menos flexible.
El uso de where
permite lidiar con casos en los que están involucrados múltiples tipos.
Es posible que aún desee redactar protocolos para su reutilización en múltiples lugares, o simplemente para darle al protocolo compuesto un nombre significativo.
Swift 3 ofrece hasta 3 formas diferentes de declarar su función.
protocol SomeProtocol {
/* ... */
}
protocol SomeOtherProtocol {
/* ... */
}
1. Usando &
operador
func someFunc<T: SomeProtocol & SomeOtherProtocol>(arg: T) {
/* ... */
}
2. Usando la cláusula where
func someFunc<T>(arg: T) where T: SomeProtocol, T: SomeOtherProtocol {
/* ... */
}
3. Usando la cláusula where
y el operador &
func someFunc<T>(arg: T) where T: SomeProtocol & SomeOtherProtocol {
/* ... */
}
También tenga en cuenta que puede usar typealias
para acortar la declaración de su función.
typealias RequiredProtocols = SomeProtocol & SomeOtherProtocol
func someFunc<T: RequiredProtocols>(arg: T) {
/* ... */
}
Tienes dos posibilidades:
Usas una cláusula where como se indica en la respuesta de Jiaaro:
func someFunc<T where T : SomeProtocol, T : SomeOtherProtocol>(arg: T) { // do stuff }
Utiliza un tipo de composición de protocolo :
func someFunc<T : protocol<SomeProtocol, SomeOtherProtocol>>(arg: T) { // do stuff }