繁体   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