簡體   English   中英

Swift中的設置和協議

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

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM