swift swift2 protocols equatable

El protocolo Swift implementa Equatable



swift2 protocols (2)

1) Permita que se Cacheable dos Cacheable s del mismo tipo

protocol Cacheable: Equatable { //....// func identifier() -> String } func ==<T : Cacheable>(lhs: T, rhs: T) -> Bool { return lhs.identifier() == rhs.identifier() }

Pros

Esta es la solución más simple.

Contras

Solo puede comparar dos objetos Cacheable del mismo tipo. Esto significa que el código a continuación fallará y para corregirlo debe hacer que Animal ajuste a Cacheable :

class Animal { } class Dog: Animal,Cacheable { func identifier() -> String { return "object" } } class Cat: Animal,Cacheable { func identifier() -> String { return "object" } } let a = Dog() let b = Cat() a == b //such comparison is not allowed

2) Permitir que se Cacheable las Cacheable de cualquier tipo

protocol Cacheable:Equatable { //....// func identifier() -> String } func ==<T:Cacheable>(lhs: T, rhs: T) -> Bool { return lhs.identifier() == rhs.identifier() } func !=<T:Cacheable>(lhs: T, rhs: T) -> Bool { return lhs.identifier() != rhs.identifier() } func ==<T:Cacheable, U:Cacheable>(lhs: T, rhs: U) -> Bool { return lhs.identifier() == rhs.identifier() } func !=<T:Cacheable, U:Cacheable>(lhs: T, rhs: U) -> Bool { return lhs.identifier() != rhs.identifier() }

Pros

Elimina las limitaciones descritas anteriormente para la solución 1. Ahora puede comparar fácilmente el Dog y el Cat .

Contras

  • La implementación es más larga. En realidad, no estoy seguro de por qué especificar solo funciones == no es suficiente, esto podría ser un error con un compilador. De todos modos, debe proporcionar la implementación tanto para == como para != .
  • En algunos casos, el beneficio de esta implementación también puede plantear un problema ya que permite la comparación entre objetos absolutamente diferentes y el compilador está totalmente de acuerdo.

3) Sin conformidad con Equatable

protocol Cacheable { //....// func identifier() -> String } func ==(lhs: Cacheable, rhs: Cacheable) -> Bool { return lhs.identifier() == rhs.identifier() } func !=(lhs: Cacheable, rhs: Cacheable) -> Bool { return lhs.identifier() != rhs.identifier() }

Pros

Puede usar Cacheable como tipo sin necesidad de genéricos. Esto introduce una nueva gama de posibilidades. Por ejemplo:

let c:[Cacheable] = [Dog(),RaceCar()] c[0] == c[1] c[0] != c[1]

Con las soluciones 1 y 2, dicho código fallaría y tendría que usar genéricos en sus clases. Sin embargo, con la última implementación Cacheable se trata como un tipo, por lo que se le permite declarar una matriz de tipo [Cacheable] .

Contras

Ya no declaras la conformidad con Equatable por lo que cualquier función que acepte parámetros Equatable no aceptará Cacheable . Obviamente, aparte de == y != Como los Cacheable para Cacheable s.

Si esto no es un problema en tu código, preferiría esta solución. Ser capaz de tratar el protocolo como un tipo es muy útil en muchos casos.

Tengo el siguiente Protocol :

protocol Cacheable { //....// func identifier() -> String }

¿Puedo hacer que Cacheable implemente Equatable?

cuando hago lo siguiente:

extension Cacheable: Equatable {} func ==(lhs:Cacheable,rhs:Cacheable) -> Bool { return lhs.identifier() == rhs.identifier() }

Recibí este mensaje de error: Extensión del protocolo Cacheable no puede tener una cláusula de herencia


Tratar.

extension Equatable where Self : Cacheable { }