medium - swift protocol and delegate example
Protocolo Swift con la cláusula "donde el Yo" (1)
Además de esta sintaxis con una extensión de protocolo:
protocol P {}
extension P where Self : UIView {}
... Descubrí por accidente que puedes usar la misma cláusula where en el protocolo mismo:
protocol P where Self : UIView {}
Tenga en cuenta que esto no es lo mismo que una cláusula where que restringe un protocolo genérico, y no hace de P un protocolo genérico.
Mis experimentos parecen mostrar que solo se pueden usar dos puntos aquí, y la cosa después de los dos puntos debe ser una clase o un protocolo (que puede ser genérico).
Me puse curioso: ¿cómo se me escapó esto? Así que fui a buscar evidencia de cuando surgió. En Swift 3.0, la primera sintaxis es legal pero no la última. En Swift 3.3, ambos son legales. Así que la última sintaxis debe haberse introducido silenciosamente en algo como Swift 3.2. Digo "en voz baja" porque no puedo encontrar nada al respecto en las notas de la versión.
¿Para qué sirve la segunda sintaxis? ¿Es, como parece, solo una forma conveniente de asegurarse de que ningún otro tipo pueda adoptar este protocolo? Los encabezados Swift no parecen hacer uso de ellos.
La capacidad de poner restricciones de superclase en declaraciones de protocolos (es decir, poder definir el
protocol P where Self : C
donde
C
es el tipo de una clase) fue una consecuencia prematura de
SE-0156
, y la sintaxis debería haberse rechazado en Swift 4.x hasta que se implementó la función.
Intentar usar esta función en Swift 4.x
.com/a/50647762/2976878
, así que evitaría usarla hasta Swift 5.
En Swift 5 (Xcode 10.2) la característica ahora se ha implementado . De las notas de publicación :
Los protocolos ahora pueden restringir sus tipos conformes a aquellos que subclasifican una clase dada. Se admiten dos formas equivalentes:
protocol MyView: UIView { /*...*/ } protocol MyView where Self: UIView { /*...*/ }
Swift 4.2 aceptó el segundo formulario, pero no se implementó por completo y, a veces, podría fallar en tiempo de compilación o tiempo de ejecución. ( SR-5581 ) (38077232)
Esta sintaxis coloca una restricción de superclase en
MyView
que restringe los tipos conformes a aquellos que heredan de (o son)
UIView
.
Además, el uso de
MyView
es semánticamente equivalente a una clase existencial (por ejemplo,
UIView & MyView
) en que puede acceder tanto a los miembros de la clase como a los requisitos del protocolo en el valor.
Por ejemplo, ampliando el ejemplo de las notas de publicación:
protocol MyView : UIView {
var foo: Int { get }
}
class C : MyView {} // error: ''P'' requires that ''C'' inherit from ''UIView''
class CustomView : UIView, MyView {
var foo: Int = 0
}
// ...
let myView: MyView = CustomView(frame: .zero)
// We can access both `UIView` members on a `MyView` value
print(myView.backgroundColor as Any)
// ... and `MyView` members as usual.
print(myView.foo)