【问题标题】:Swift - Can I make a protocol Hashable?Swift - 我可以制作一个可散列的协议吗?
【发布时间】:2020-08-19 09:39:53
【问题描述】:

我写了一个简单的协议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 ?? "")
    }    
}
// ...

我想知道的是是否可以从其objectId 中将Data 一般声明为Hashable。由于我使用的是协议,所以我找不到这样做的方法。

感谢您的帮助。

【问题讨论】:

  • 使用[String:Any] 会破坏Hashable 一致性的自动综合。将state 存储为[String:Any] 是一个非常糟糕的主意。
  • 数据是原生的 Swift 类型,你应该为你的协议使用另一个名字

标签: swift protocols hashable


【解决方案1】:

正如@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) {
    
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多