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 cumplir SomeProtocol
, podría hacer:
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>
Respuestas:
Puede usar una cláusula where que le permite especificar tantos requisitos como desee (todos los cuales deben cumplirse) separados por comas
Swift 2:
Swift 3 y 4:
o la cláusula where más poderosa:
Por supuesto, puede usar la composición del protocolo (por ejemplo,
protocol<SomeProtocol, SomeOtherProtocol>
), pero es un poco menos flexible.El uso le
where
permite tratar casos en los que intervienen varios tipos.Es posible que aún desee componer protocolos para su reutilización en varios lugares, o simplemente para dar al protocolo compuesto un nombre significativo.
Swift 5:
Esto se siente más natural ya que los protocolos están al lado del argumento.
fuente
<T where T:SomeStruct, T:AnotherStruct>
? Para las clases, el compilador parece interpretar esto como diciendo "T es una subclase de ambos", y para las estructuras simplemente se queja de eso"Type 'T' constrained to non-protocol type"
.where
cláusula para el uso adicional de tipos / otros, por ejemplo,func someFunc<U, T: protocol<SomeProtocol, SomeOtherProtocol> where T.SubType == U>(arg: T, arg2: U) { ... }
para los typealiasSubType
en, por ejemploSomeProtocol
.Tienes dos posibilidades:
Utiliza una cláusula where como se indica en la respuesta de Jiaaro:
Utiliza un tipo de composición de protocolo :
fuente
typealias
. ¡Gracias!La evolución a Swift 3.0 trae algunos cambios. Nuestras dos opciones ahora se ven un poco diferentes.
Usando una
where
cláusula en Swift 3.0:La
where
cláusula ahora se ha movido al final de una firma de función para mejorar la legibilidad. Entonces, la herencia de múltiples protocolos ahora se ve así:Usando la
protocol<>
construcción en Swift 3.0:La composición que usa la
protocol<>
construcción está en desuso. Lo anteriorprotocol<SomeProtocol, SomeOtherProtocol>
ahora se ve así:Referencias
Aquí encontrará más información sobre los cambios
where
: https://github.com/apple/swift-evolution/blob/master/proposals/0081-move-where-expression.mdY, 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
fuente
Swift 3 ofrece hasta 3 formas diferentes de declarar su función.
1. Usando
&
operador2. Usando la
where
cláusula3. Usando
where
cláusula y&
operadorTambién tenga en cuenta que puede usar
typealias
para acortar su declaración de función.fuente