我想用Hashable协议和自定义协议对应的值初始化Set。在Swift中设置和协议
我想:
protocol CustomProtocol: Hashable {}
let set = Set<CustomProtocol>()
但Xcode的抱怨:
使用 'CustomProtocol' 作为具体类型符合协议 '哈希的' 不支持
如何我做到了吗?
在此先感谢。
我想用Hashable协议和自定义协议对应的值初始化Set。在Swift中设置和协议
我想:
protocol CustomProtocol: Hashable {}
let set = Set<CustomProtocol>()
但Xcode的抱怨:
使用 'CustomProtocol' 作为具体类型符合协议 '哈希的' 不支持
如何我做到了吗?
在此先感谢。
为什么你不能做你想做的事情的直接原因是Hashable是一个通用的协议。因此它或者从它派生的协议不能用作Set的元素类型。泛型类型只能用作另一个泛型中的约束。你会注意到,即使一个集合的元素类型必须符合到Hashable,你也不能声明Set<Hashable>
。
最简单的方法是,不是一组协议,而是一组对象类型。例如,如果S是符合CustomProtocol(因为它符合哈希的加任何其他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 structure。
例如,创建一个观察员/可观察的模式,我们可以这样做:
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) }
}
}
请注意,我从我的协议Observer
分开Hashable
协议。
已经需要符合Hashable的对象。 – Abizern
如果CustomProtocol不符合Hashable,则Xcode会抱怨CustomProtocol不符合它。看起来我错过了一些东西。 –