我认为您的主要目标是保存符合某些协议的对象集合,添加到该集合并从中删除。这是您的客户端“SomeClass”中所述的功能。Equatable 继承需要 self ,而此功能不需要。我们本可以在 Obj-C 中的数组中使用可以采用自定义比较器的“索引”函数来完成这项工作,但这在 Swift 中不受支持。所以最简单的解决方案是使用字典而不是数组,如下面的代码所示。我提供了 getElements() ,它将返回您想要的协议数组。所以任何使用 SomeClass 的人甚至都不知道使用了字典来实现。
因为在任何情况下,您都需要一些可区分的属性来分隔您的对象,所以我假设它是“名称”。当你创建一个新的 SomeProtocol 实例时,请确保你的 do element.name = "foo" 。如果未设置名称,您仍然可以创建实例,但不会将其添加到集合中,并且 addElement() 将返回“false”。
protocol SomeProtocol {
var name:String? {get set} // Since elements need to distinguished,
//we will assume it is by name in this example.
func bla()
}
class SomeClass {
//var protocols = [SomeProtocol]() //find is not supported in 2.0, indexOf if
// There is an Obj-C function index, that find element using custom comparator such as the one below, not available in Swift
/*
static func compareProtocols(one:SomeProtocol, toTheOther:SomeProtocol)->Bool {
if (one.name == nil) {return false}
if(toTheOther.name == nil) {return false}
if(one.name == toTheOther.name!) {return true}
return false
}
*/
//The best choice here is to use dictionary
var protocols = [String:SomeProtocol]()
func addElement(element: SomeProtocol) -> Bool {
//self.protocols.append(element)
if let index = element.name {
protocols[index] = element
return true
}
return false
}
func removeElement(element: SomeProtocol) {
//if let index = find(self.protocols, element) { // find not suported in Swift 2.0
if let index = element.name {
protocols.removeValueForKey(index)
}
}
func getElements() -> [SomeProtocol] {
return Array(protocols.values)
}
}