programacion - protocolos swift
Swift 2 aƱade la conformidad del protocolo a los protocolos. (2)
¿Este patio hace lo que quieres? Lo hice en base a lo que entiendo de la Programación Orientada a Protocolo en Swift de WWDC 2015.
import Foundation
//Plain old protocol here
func == (lhs: MyData, rhs: MyData) -> Bool {
return lhs.myDataID == rhs.myDataID
}
func != (lhs: MyData, rhs: MyData) -> Bool {
return lhs.myDataID != rhs.myDataID
}
protocol MyData {
var myDataID: Int { get }
}
extension MyData where Self: Equatable {
}
struct BananaData: MyData {
var myDataID: Int = 1
}
func checkEquatable(bananaOne: BananaData, bananaTwo: BananaData) {
//This compiles, verifying that BananaData can be compared
if bananaOne == bananaTwo {
print("Same")
}
//But BananaData is not convertible to Equatable, which is what I want
//I don''t get the additional operations added to Equatable (!=)
print(bananaOne.myDataID)
print(bananaTwo.myDataID)
if bananaOne != bananaTwo {
}
//Error
}
let b1 = BananaData(myDataID: 2)
let b2 = BananaData(myDataID: 2)
checkEquatable(b1, bananaTwo: b2)
let c = b1 == b2 // Evaluates as true
¿Puedo agregar la conformidad del protocolo a un protocolo a través de una extensión rápida?
//Plain old protocol here
protocol MyData {
var myDataID: Int { get }
}
Quiero hacer que el protocolo MyData sea equiparable de forma predeterminada (solo compare el ID)
extension MyData : Equatable { }
Pero me sale este error encantador:
"La extensión del protocolo ''MyData'' no puede tener una cláusula de herencia"
El comportamiento que busco es BananaData conforme a Equatable (un protocolo) porque implementa el protocolo MyData que puede proporcionar una implementación predeterminada de Equatable
//This is the method to implement Equatable
func ==(lhs: MyData, rhs: MyData) -> Bool {
return lhs.myDataID == rhs.myDataID
}
struct BananaData: MyData {
var myDataID: Int = 1
}
func checkEquatable(bananaOne: BananaData, bananaTwo: BananaData) {
//This compiles, verifying that BananaData can be compared
if bananaOne == bananaTwo { }
//But BananaData is not convertible to Equatable, which is what I want
let equatableBanana = bananaOne as Equatable
//I don''t get the additional operations added to Equatable (!=)
if bananaOne != bananaTwo { } //Error
}
Como dice el mensaje de error: una extensión de un protocolo no puede tener una cláusula de herencia. En su lugar, puede hacer que el protocolo MyData
herede de Equatable
en la declaración original.
protocol MyData: Equatable {
var myDataID: Int { get }
}
A continuación, puede extender y agregar una implementación de ==
para los tipos que se ajustan a MyData
:
func == <T: MyData>(lhs: T, rhs: T) -> Bool {
return lhs.myDataID == rhs.myDataID
}
Sin embargo, yo no recomendaría esto! Si agrega más propiedades a los tipos conformes, no se verificará la igualdad de sus propiedades. Tomemos el siguiente ejemplo:
struct SomeData: MyData {
var myDataID: Int
var myOtherData: String
}
let b1 = SomeData(myDataID: 1, myOtherData: "String1")
let b2 = SomeData(myDataID: 1, myOtherData: "String2")
b1 == b2 // true, although `myOtherData` properties aren''t equal.
En el caso anterior, tendría que anular ==
para SomeData
para obtener el resultado correcto, por lo que el ==
que acepta MyData
redundante.