比较协议引用

时间:2014-08-04 10:10:30

标签: arrays swift compare protocols

我有一系列协议。现在我想通过查找数组的协议索引从数组中删除一个项目。但是,在将协议对象与数组中的项进行比较时,编译器会发出警告:

  

'协议'不符合AnyObject

protocol SomeProtocol {}
var list:[SomeProtocol] = []
func add(some:SomeProtocol) { list+=some }
func remove(some:SomeProtocol) {
    var index = -1
    for i in 0...list.count-1 { if [i] === some { index = i } }
    if index >= 0 { list.removeAtIndex(index) }
}

3 个答案:

答案 0 :(得分:15)

如果只派生协议类,则可以将协议定义更改为:

protocol SomeProtocol: class {}

然后,您将能够使用此协议的引用。

答案 1 :(得分:2)

首先,执行add非常简单,只需包含此功能即可使其正常工作:

func +=(inout lhs: [SomeProtocol], rhs: SomeProtocol) {
    lhs.append(rhs)
}

执行remove要复杂得多,因为SomeProtocol可以同等地应用于classstruct,只有类类型的值可以与{{1}进行比较}。

我们可以使用===运算符,但它只需要符合==协议的值,而Equatable只能用作泛型约束(到目前为止),否则你可以使用像Equatable这样的数组元素类型。

如果您确定将protocol<SomeProtocol,Equatable> 应用于类,请考虑重构代码以使用该类类型:

SomeProtocol

如果您碰巧使protocol SomeProtocol {} class SomeClass : SomeProtocol {} var list:[SomeClass] = [] func add(some:SomeClass) { list += some } func remove(some:SomeClass) { list -= some } func +=(inout lhs: [SomeClass], rhs: SomeClass) { lhs.append(rhs) } func -=(inout lhs: [SomeClass], rhs: SomeClass) { for (i,v) in enumerate(lhs) { if v === rhs { lhs.removeAtIndex(i) break } } } 符合SomeClass,则通常的数组函数会自动生效,您甚至不需要重载Equatable和{{1} }。

否则,如果你不能知道你的价值是一个阶级还是一个结构,那么最好考虑一下+=的值是什么意思?#34;等于&# 34;并要求比较方法:

-=

或者,您可以使用原始代码并编写全局比较函数:

SomeProtocol

答案 2 :(得分:0)

我最终在我的协议中使用isEqual(to :)来测试实例比较:

public protocol fooProtocol {
    ...
    func isEqual(to: fooProtocol) -> Bool
}

public extension fooProtocol {
    func isEqual(to: fooProtocol) -> Bool {
        let ss = self as! NSObject
        let tt = to as! NSObject
        return ss === tt
    }
}

似乎适合我。