如何基于实现该协议的两个实例的身份为协议实现平等协议?

sal*_*inx 5 protocols ios swift equatable swift4

我正在尝试为基于左操作数和右操作数标识的协议实现Equatable协议。换句话说:我如何为一个协议实现Equatable协议,以确定实现此协议的两个实例(在我的情况下iNetworkSubscriber)是否相同(相同的对象引用)。这样(错误消息包含在下面的代码中):

protocol iNetworkSubscriber : Equatable {

    func onMessage(_ packet: NetworkPacket)

}

func ==(lhs: iNetworkSubscriber, rhs: iNetworkSubscriber) -> Bool {     // <- Protocol 'iNetworkSubscriber' can only be used as a generic constraint because it has Self or associated type requirements
    return ObjectIdentifier(lhs) == ObjectIdentifier(rhs)               // <- Cannot invoke initializer for type 'ObjectIdentifier' with an argument list of type '(iNetworkSubscriber)'
}
Run Code Online (Sandbox Code Playgroud)

......我也与身份运营商自己试了一下:

func ==(lhs: iNetworkSubscriber, rhs: iNetworkSubscriber) -> Bool {     // <- Protocol 'iNetworkSubscriber' can only be used as a generic constraint because it has Self or associated type requirements
    return lhs === rhs                                                  // <- Binary operator '===' cannot be applied to two 'iNetworkSubscriber' operands
}
Run Code Online (Sandbox Code Playgroud)

有人的想法如何解决这个问题呢?

Rob*_*ier 3

这里有两个问题。首先是您不能ObjectIdentifier在值类型上使用。因此,您必须声明此协议需要引用(类)类型:

protocol NetworkSubscriber : class, Equatable {
    func onMessage(_ packet: NetworkPacket)
}
Run Code Online (Sandbox Code Playgroud)

(请勿添加小写字母i在协议的开头添加小写字母。这在 Swift 中会在很多方面造成混淆。)

那么,您就不能将此协议用作类型。它描述了一种类型(因为它依赖于Selfvia Equatable)。因此接受它的函数必须是通用的。

func ==<T: NetworkSubscriber>(lhs: T, rhs: T) -> Bool {
    return ObjectIdentifier(lhs) == ObjectIdentifier(rhs)
}
Run Code Online (Sandbox Code Playgroud)

鉴于它NetworkSubscriber必须是一个类,您应该非常仔细地询问是否应该在此处使用继承而不是协议。具有关联类型的协议使用起来非常复杂,并且混合类和协议会产生更大的复杂性。如果您已经在使用类,则类继承会简单得多。