Swift 2 - 符合Equatable问题的协议

Mar*_*ark 3 ios swift2

我在下面定义的协议存在问题.我有两个要求:

  1. 我希望能够将协议Peer用作其他类中的类型,同时保持具体类的私有性.
  2. 我想将协议存储在一个数组中,并能够确定实例的索引.

为了满足第二点,我需要使协议符合Equatable协议.但是当我这样做时,我不能再将其Peer用作类型,因为它需要被视为通用类型.这意味着我不能再具有私有的具体实现,并且要求1被打破.

想知道是否有其他人遇到过这个问题并以某种方式绕过它.也许我误解了我所得到的错误indexOf......

Group.swift

import Foundation

class Group {
    var peers = [Peer]()

    init() {
        peers.append(PeerFactory.buildPeer("Buddy"))
    }

    func findPeer(peer: Peer) -> Bool {
        if let index = peers.indexOf(peer) {
            return true
        }
        return false
    }
}
Run Code Online (Sandbox Code Playgroud)

Peer.swift

import Foundation

protocol Peer {
    var name: String { get }
}

class PeerFactory {
    static func buildPeer(name: String) -> Peer {
        return SimplePeer(name: name)
    }
}

private class SimplePeer: Peer {
    let name: String

    init(name: String) {
        self.name = name
    }
}
Run Code Online (Sandbox Code Playgroud)

错误的indexOf,如果Peer没有 Equatable:

cannot convert value of type 'Peer' to expected argument type '@noescape (Peer) throws -> Bool'
Run Code Online (Sandbox Code Playgroud)

Mar*_*ark 5

所以我找到了一个解决方案,Equatable通过扩展CollectionType来定义一个新的indexOffor元素Peer类型,从而利用其他基于闭包的方法来解决这个问题indexOf.这本质上是一个方便的功能,使我免于indexOf直接使用闭包.代码如下:

extension CollectionType where Generator.Element == Peer {
    func indexOf(element: Generator.Element) -> Index? {
        return indexOf({ $0.name == element.name })
    }
}
Run Code Online (Sandbox Code Playgroud)

这当然假设我需要测试相等性的所有东西都可以从Peer协议中获得(对于我的特定用例来说是这样).

编辑: Swift 3的更新:

extension Collection where Iterator.Element == Peer {
    func indexOf(element: Iterator.Element) -> Index? {
        return index(where: { $0.name == element.name })
    }
}
Run Code Online (Sandbox Code Playgroud)