斯威夫特协议实现平等

斯威夫特协议实现平等

本文介绍了斯威夫特协议实现平等的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有以下Protocol:

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

我可以使Cacheable实现Equatable吗?

Can I make Cacheable implements Equatable ?

当我执行以下操作时:

extension Cacheable: Equatable {}

func ==(lhs:Cacheable,rhs:Cacheable) -> Bool {

     return lhs.identifier() == rhs.identifier()
}

我收到此错误消息:协议Cacheable的扩展不能有继承子句

I got this error message : Extension of protocol Cacheable cannot have an inheritance clause

推荐答案

1)允许比较两个相同类型的Cacheable

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

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

专业人士

这是最简单的解决方案.

Pros

This is the simplest solution.

您只能比较两个相同类型的Cacheable对象.这意味着下面的代码将失败,为了对其进行修复,您需要使Animal符合Cacheable:

You can only compare two Cacheable objects of the same type. This means that code below will fail and in order to fix it you need to make Animal conform to 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)允许比较任何类型的Cacheable

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()
}

专业人士

消除了上述解决方案1的局限性.现在,您可以轻松比较DogCat.

  • 实施时间更长.实际上,我不确定为什么仅指定==函数是不够的-这可能是编译器的错误.无论如何,您必须同时提供==!=的实现.
  • 在某些情况下,此实现的好处也可能会带来问题,因为您允许在绝对不同的对象之间进行比较,并且编译器完全可以这样做.
  • Implementation is longer. Actually I am not sure why specifying only == functions is not sufficient - this might be a bug with a compiler. Anyway, you have to provide the implementation for both == and !=.
  • In some cases the benefit of this implementation may also pose a problem as you are allowing the comparison between absolutely different objects and compiler is totally OK with it.
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()
}

专业人士

您可以使用Cacheable作为类型,而无需任何泛型.这引入了全新的可能性.例如:

Pros

You can use Cacheable as type without needing any generics. This introduces a whole new range of possibilities. For example:

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

c[0] == c[1]
c[0] != c[1]

对于解决方案1和2,此类代码将失败,并且您将不得不在类中使用泛型.但是,在最新的实现中,Cacheable被视为类型,因此您可以声明类型为[Cacheable]的数组.

With solutions 1 and 2 such code would fail and you would have to use generics in your classes. However, with the latest implementation Cacheable is treated as a type, so you are allowed to declare an array of type [Cacheable].

您不再声明符合Equatable,因此任何接受Equatable参数的函数将不接受Cacheable.显然,除了==!=,我们在Cacheable s中声明了它们.

You no longer declare conformance to Equatable so any functions which accept Equatable parameters will not accept Cacheable. Obviously, apart from == and != as we declared them for Cacheables.

如果这不是您的代码中的问题,我实际上会更喜欢此解决方案.在许多情况下,能够将协议视为类型非常有用.

If this is not a problem in your code I would actually prefer this solution. Being able to treat protocol as a type is super useful in many cases.

这篇关于斯威夫特协议实现平等的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-14 02:01