问题描述
我写了一个简单的协议Data
:
public protocol Data {
var state: [String: Any] { get set }
var objectId: String? { get set }
}
public extension Data {
var objectId: String? {
get {
return self.state["objectId"] as? String
}
set {
self.state["objectId"] = newValue
}
}
}
这样,我创建了几种符合它的类型:
public struct Person: Data {
public var state: [String : Any]
}
public struct Car: Data {
public var state: [String : Any]
}
// ...
现在我要做的是使每种类型都Hashable
,问题是我需要在每种类型中编写以下代码:
extension Car Hashable {
public static func == (lhs: Car,rhs: Car) -> Bool {
return lhs.objectId == rhs.objectId
}
public func hash(into hasher: inout Hasher) {
hasher.combine(self.objectId ?? "")
}
}
// ...
我想知道的是,是否有可能将Data
的{{1}}声明为Hashable
。当我使用协议时,找不到任何方法。
谢谢您的帮助。
解决方法
正如@Leo Dabus在他的评论中提到的,由于本机Foundation.Data
类型的存在,您可能应该为协议使用另一个名称。
无论哪种方式,都可以使用以下代码在您的Hashable
协议中实现Data
协议:
public protocol Data: Hashable {
var state: [String: Any] { get set }
var objectId: String? { get set }
}
public extension Data {
var objectId: String? {
get {
return self.state["objectId"] as? String
}
set {
self.state["objectId"] = newValue
}
}
static func == (lhs: Self,rhs: Self) -> Bool {
return lhs.objectId == rhs.objectId
}
func hash(into hasher: inout Hasher) {
hasher.combine(self.objectId ?? "")
}
}
尽管这会带来副作用,因为协议Data
具有自身或相关类型要求,因此只能用作通用约束:
这意味着您现在可以像这样使用Data
协议:
func myFunc<T: Data>(data: T) {
}