[英]Set and protocols in Swift
我想初始化一个Set,其中包含与Hashable协议和自定义协议相对应的值。
我试过了 :
protocol CustomProtocol: Hashable {}
let set = Set<CustomProtocol>()
但是Xcode抱怨道:
不支持使用'CustomProtocol'作为符合协议'Hashable'的具体类型
我怎样才能做到这一点?
提前致谢。
你不能做你想做的事情的直接原因是Hashable是一种通用协议。 因此,它 - 或从中派生的协议 - 不能用作Set的元素类型。 泛型类型只能用作另一个泛型中的约束。 您会注意到,即使set的元素类型必须符合 Hashable,也不能声明Set<Hashable>
。
最简单的方法是制作一组协议,而不是一组对象类型。 例如,如果S是符合CustomProtocol的结构(因为它符合Hashable加上CustomProtocol所需的任何其他内容),则可以声明一组S.
例:
protocol CustomProtocol: Hashable {
}
func ==(lhs:S,rhs:S) -> Bool {
return lhs.name == rhs.name
}
struct S : CustomProtocol {
var name : String
var hashValue : Int { return name.hashValue }
}
let set = Set<S>()
如果你想要解决的问题是你想要一个混合类型的集合,但它们在某种程度上是彼此相同的,那么协议扩展就解决了同样的问题,正如协议中的讨论所解释的那样 - 面向WWDC 2015的视频。
但是,只需要创建从NSObject派生的所有类型类就更简单了。 当然,你仍然可以让它们采用一些辅助协议,但是这个集合不会被定义为一组协议而是NSObject。
在Swift 3中,一种解决方案是使用AnyHashable结构 。
例如,要创建Observers / Observable模式,我们可以:
protocol Observer {
func observableDidSomething(_ observable: Observable)
}
class Observable {
private var observersSet: Set<AnyHashable> = []
private var observers: [Observer] {
return observersSet.flatMap { $0 as? Observer }
}
func add<O>(_ observer: O) where O : Observer, O : Hashable {
observersSet.insert(observer)
}
func remove<O>(_ observer: O) where O : Observer, O : Hashable {
observersSet.remove(observer)
}
// ...
private func doSomething() {
// do something ...
observers.forEach { $0.observableDidSomething(self) }
}
}
请注意,我将Hashable
协议与我的协议Observer
分开。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.