我有一系列协议。现在我想通过查找数组的协议索引从数组中删除一个项目。但是,在将协议对象与数组中的项进行比较时,编译器会发出警告:
'协议'不符合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) }
}
答案 0 :(得分:15)
如果只派生协议类,则可以将协议定义更改为:
protocol SomeProtocol: class {}
然后,您将能够使用此协议的引用。
答案 1 :(得分:2)
首先,执行add
非常简单,只需包含此功能即可使其正常工作:
func +=(inout lhs: [SomeProtocol], rhs: SomeProtocol) {
lhs.append(rhs)
}
执行remove
要复杂得多,因为SomeProtocol
可以同等地应用于class
或struct
,只有类类型的值可以与{{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
}
}
似乎适合我。