Swift - 我可以使协议 Hashable 吗?

Swift - Can I make a protocol Hashable?

我写了一个简单的协议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。由于我正在使用协议,因此我找不到这样做的方法。

感谢您的帮助。

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