Swift -类型“”不符合协议“哈希"

zqdjd7g9  于 2022-12-17  发布在  Swift
关注(0)|答案(2)|浏览(224)

所以我有这样的结构:

struct ListAction: Hashable {
    let label: String
    let action: (() -> Void)? = nil
    let command: Command? = nil
}

但是我在声明Type 'ListAction' does not conform to protocol 'Hashable'的行上得到了一个错误。
如果我删除定义action常量的行,我可以消除这个错误,但是我不想永久删除该行。
我用的是Swift 5.1.

yb3bgrhw

yb3bgrhw1#

通过重写hash(into:)并在所有相关属性上调用combine,为Hashable提供您自己的实现。

struct ListAction: Hashable {
    static func == (lhs: ListAction, rhs: ListAction) -> Bool {
        return lhs.label == rhs.label && lhs.command == rhs.command
    }

    func hash(into hasher: inout Hasher) {
        hasher.combine(label)
        hasher.combine(command)
    }

    let label: String
    let action: (() -> Void)? = nil
    let command: Command? = nil
}
lyr7nygr

lyr7nygr2#

该结构需要一个唯一标识符才能符合Hashable。您只需向结构添加一个UID,然后添加一个哈希函数作为比较函数来进行比较。

struct ListAction: Codable, Hashable {
    var uid = UUID().uuidString
    let label: String
    let action: (() -> Void)? = nil
    let command: Command? = nil
    
    static func == (lhs: Self, rhs: Self) -> Bool {
        return lhs.uid == rhs.uid
    }
    
    func hash(into hasher: inout Hasher) {
        hasher.combine(uid)
    }
    
}

你可以把这两个函数和var uid添加到任何你在创建哈希时遇到问题的结构体中。
向需要协议函数(如hash)的结构体添加扩展是一个很好的实践。

struct ListAction {
var uid = UUID().uuidString // add this 
    let label: String
    let action: (() -> Void)? = nil
    let command: Command? = nil
}    
// add this to make your struct conform to Hashable
extension ListAction: Hashable {
        static func == (lhs: Self, rhs: Self) -> Bool {
            lhs.uid == rhs.uid
        }
        func hash(into hasher: inout Hasher) {
            hasher.combine(uid)
        }
    }

相关问题