【问题标题】:Find index of object in an array of type [SomeProtocol]在 [SomeProtocol] 类型的数组中查找对象的索引
【发布时间】:2026-02-20 05:50:02
【问题描述】:

我有一个称为订阅者的数组,它存储符合 JABPanelChangeSubscriber 协议的对象。协议声明为

public protocol JABPanelChangeSubscriber {

}

我的数组被声明为:

var subscribers = [JABPanelChangeSubscriber]()

现在我需要实现一个方法来将订阅者添加到列表中,但它首先必须检查该订阅者之前是否尚未添加。

public func addSubscriber(subscriber: JABPanelChangeSubscriber) {
    if subscribers.find(subscriber) == nil { // This ensures that the subscriber has never been added before
        subscribers.append(subscriber)
    }
}

不幸的是,JABPanelChangeSubscriber 不是 Equatable,我不知道如何使它 Equatable,所以 find 方法给了我一个错误。任何人都可以帮助我解决问题或提出不同方法的建议吗?

谢谢

【问题讨论】:

  • 你为什么使用subscribers.find()?除非你为Array 写了一个扩展,否则我认为默认的Array 没有find() 方法。

标签: arrays xcode swift protocols iequatable


【解决方案1】:

假设实现你的协议的所有类型都是引用类型 (类),您可以将协议声明为“类协议”

public protocol JABPanelChangeSubscriber : class {

}

并使用身份运算符 === 检查数组是否已经 包含指向与给定参数相同的实例的元素:

public func addSubscriber(subscriber: JABPanelChangeSubscriber) {
    if !contains(subscribers, { $0 === subscriber } ) {
        subscribers.append(subscriber)
    }
}

【讨论】:

    【解决方案2】:

    isEqualTo(:) 要求添加到JABPanelChangeSubscriber 协议

    public protocol JABPanelChangeSubscriber {
        func isEqualTo(other: JABPanelChangeSubscriber) -> Bool
    }
    

    JABPanelChangeSubscriber 协议的扩展,需要 Self

    extension JABPanelChangeSubscriber where Self: Equatable {
       func isEqualTo(other: JABPanelChangeSubscriber) -> Bool {
          guard let other = other as? Self else { return false }
            return self == other
       }
    }
    

    记得让对象也符合Equatable协议

    class SomeClass: Equatable {}
    func == (lhs: SomeClass, rhs: SomeClass) -> Bool {
    //your code here
    //you could use `===` operand
    }
    
    struct SomeStruct: Equatable {}
    func == (lhs: SomeStruct, rhs: SomeStruct) -> Bool {
    //your code here
    }
    

    然后找到索引

    func indexOf(object: JABPanelChangeSubscriber) -> Int? {
        return subcribers.indexOf({ $0.isEqualTo(object) })
    }
    

    如果要在将对象添加到数组之前检查对象是否存在

    func addSubscriber(subscriber: JABPanelChangeSubscriber) {
        if !subscribers.contains({ $0.isEqualTo(subscriber) }) {
            subscribers.append(subscriber)
        }
    }
    

    【讨论】:

      最近更新 更多