在Swift中设置和协议

我想用Hashable协议和自定义协议来初始化一个Set值。

我试过了 :

protocol CustomProtocol: Hashable {} let set = Set<CustomProtocol>() 

但Xcode抱怨:

不支持使用“CustomProtocol”作为符合协议“Hashable”的具体types

我怎样才能做到这一点?

提前致谢。

为什么你不能做你想做的直接原因是Hashable是一个通用的协议。 因此,它或者从它派生的协议不能用作Set的元素types。 generics只能用作另一个generics的约束。 你会注意到,即使一个set的元素types必须符合 Hashable,你也不能声明Set<Hashable>

最简单的方法是,不是一组协议,而是一组对象types。 例如,如果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>() 

如果你试图解决的问题是你想要一些混合types的集合,但是这些混合types在某种程度上可以相互平衡,那么协议扩展解决了这个问题,正如协议讨论中所解释的 – 面向WWDC 2015的video。

但是只要制作所有从NSObject派生的types类就简单了。 当然,你仍然可以使它们采用一些辅助协议,但是这个集合不会被定义为NSObject的一组协议。

在Swift 3中,一个解决scheme是使用AnyHashable结构 。

例如,要创build一个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) } } } 

请注意,我将我的协议ObserverHashable协议分开。