如何从数组<>中删除协议

问题描述 投票:0回答:2

我认为这很容易,但它不起作用。我有一个数组,我想从中删除一个对象。对象是类型协议。

var myArray = Array<MyProtocol>()
myArray.remove(at: protocolToRemove) 

从另一个SO问题我看到了一个Array扩展的提议,但是当我把扩展名放在另一个文件中时,它没有用。

extension Array where Element: Equatable {

    // Remove first collection element that is equal to the given `object`:
    mutating func remove(object: Element) {
        if let index = index(of: object) {
            remove(at: index)
        }
     }
}

该协议没有实现Equatable

编辑 - 添加更多信息

MyProtocol看起来像

protocol MyProtocol {
}

也试过这个,但MyProtocol不是AnyObject,即使只使用类协议。

extension Array where Element: AnyObject {
    mutating func remove(_ element: Element) {
        guard let index = index(where: { $0 === element }) else { return }
        remove(at: index)
    }

    func test() {

    }
} 
arrays swift generics
2个回答
0
投票

remove(at:)采用Int(Array的索引)。我假设protocolToRemove不是Int。

该协议没有实现Equatable

那么remove如何知道要删除哪个元素?如果它不支持==,那么唯一的另一个选择是===,在这种情况下协议必须标记为: class。在这种情况下,您可以通过以下方式删除第一个匹配元素:

protocol MyProtocol: class {
    ....
}

if index = myArray.index(where: { $0 === protocolToRemove }) {
    myArray.remove(at: index)
}

0
投票

Rob Napier和Leo Dabus让我沿着正确的道路走下去,但Equatable不是那样的选择。

如何从Array <>中删除协议?

回答

创建仅限类的协议:

protocol MyProtocol: class {
    //Stuff
}

像这样添加扩展到数组:

extension Array {
    mutating func removeObject(element: Element) {
        guard let index = index(where: { $0 as AnyObject === element as AnyObject}) else { return }
        remove(at: index)
    }
}

用法:

var myArray = Array<MyProtocol>()
var myProtocolImpl = MyProtocolImpl()

myArray.append(myProtocolImpl)
myArray.removeObject(element: myProtocolImpl)

为什么

  • 协议不是AnyObject类型。
  • 使用Array </ Protocol>从未选择AnyObject扩展。
  • 协议上的等同装饰从未获得扩展。
  • 为了基于指针地址相等来移除对象,必须比较内存位置,并且最好的方法是使用AnyObject进行仅类协议。
© www.soinside.com 2019 - 2024. All rights reserved.