[英]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.