swift - Swift - 我可以制作一个可散列的协议吗?
问题描述
我写了一个简单的协议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
从Hashable
它的objectId
. 当我使用协议时,我找不到这样做的方法。
谢谢您的帮助。
解决方案
正如@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
只能用作通用约束,因为它具有 Self 或关联的类型要求:
这意味着您现在可以Data
像这样使用协议:
func myFunc<T: Data>(data: T) {
}
推荐阅读
- jquery - 如何使用 jQuery 触发选择列表中的链接?
- r - 如何根据另一个数据框的行组织数据框的列?
- reactjs - 关于在索引页面中检索页面名称
- ios - 用于启用/禁用焦点模式的 iOS API
- python - 将 Python 函数传递给 Python 函数,但它是 C/C++ 扩展
- kotlin-coroutines - 在未指定调度程序的情况下启动的协程不会被取消
- node.js - 如何修复这个 MongoClient 连接?
- javascript - 为什么它显示空对象但仍然能够迭代?
- python - conda更新后,使用matplotlib时python内核崩溃
- node.js - 在 botsolutions 服务器上部署节点 Js 应用程序