protocolos multiple herencia swift swift-protocols

swift - multiple - ¿Por qué una propiedad que cumple no puede satisfacer un requisito de propiedad de solo obtención en un protocolo?



protocolos swift (1)

No hay una razón real por la que esto no sea posible, un requisito de propiedad de solo lectura puede ser covariante, ya que devolver una instancia de ConformsToB desde una propiedad escrita como ProtocolB es perfectamente legal.

Swift actualmente no lo admite. Para hacerlo, el compilador tendría que generar un enlace entre la tabla testigo del protocolo y la implementación conforme para realizar las conversiones de tipo necesarias. Por ejemplo, una instancia de ConformsToB debería estar encuadrada en un contenedor existencial para ser escrita como ProtocolB (y no hay forma de que la persona que llama pueda hacer esto, ya que podría no saber nada sobre la implementación que se llama).

Pero, de nuevo, no hay razón para que el compilador no pueda hacer esto. Hay varios informes de errores abiertos sobre esto, este es específico para los requisitos de propiedad de solo lectura, y este general , en el que Slava Pestov, miembro del equipo Swift, dice:

[...] queremos testigos de protocolo y anulaciones de métodos en todos los casos en que se permite una conversión de funciones

Por lo tanto, definitivamente parece algo que el equipo de Swift está buscando implementar en una versión futura del lenguaje.

Sin embargo, mientras tanto, como dice @BallpointBen , una solución alternativa es usar un tipo associatedtype :

protocol ProtocolA { // allow the conforming type to satisfy this with a concrete type // that conforms to ProtocolB. associatedtype SomeProperty : ProtocolB var someProperty: SomeProperty { get } } protocol ProtocolB {} class ConformsToB: ProtocolB {} class SomeClass: ProtocolA { // implicitly satisfy the associatedtype with ConformsToB. var someProperty: ConformsToB init(someProperty: ConformsToB) { self.someProperty = someProperty } }

Pero esto es bastante insatisfactorio, ya que significa que el ProtocolA ya no se puede usar como tipo (porque tiene requisitos de tipo associatedtype ). También cambia lo que dice el protocolo. Originalmente decía que someProperty podía devolver cualquier cosa que se ajustara al ProtocolB someProperty ; ahora dice que una implementación de someProperty trata solo de un tipo concreto específico que se ajusta al ProtocolB someProperty

Otra solución es solo definir una propiedad ficticia para satisfacer el requisito del protocolo:

protocol ProtocolA { var someProperty: ProtocolB { get } } protocol ProtocolB {} class ConformsToB: ProtocolB {} class SomeClass: ProtocolA { // dummy property to satisfy protocol conformance. var someProperty: ProtocolB { return actualSomeProperty } // the *actual* implementation of someProperty. var actualSomeProperty: ConformsToB init(someProperty: ConformsToB) { self.actualSomeProperty = someProperty } }

Aquí estamos esencialmente escribiendo el thunk para el compilador, pero tampoco es particularmente bueno ya que agrega una propiedad innecesaria a la API.

¿Por qué el siguiente código produce un error?

protocol ProtocolA { var someProperty: ProtocolB { get } } protocol ProtocolB {} class ConformsToB: ProtocolB {} class SomeClass: ProtocolA { // Type ''SomeClass'' does not conform to protocol ''ProtocolA'' var someProperty: ConformsToB init(someProperty: ConformsToB) { self.someProperty = someProperty } }

La respuesta en esta pregunta similar tiene sentido. Sin embargo, en mi ejemplo, la propiedad es get-only. ¿Por qué no debería funcionar esto? ¿Es una deficiencia de Swift, o hay alguna razón por la que esto tiene sentido?