如何在Swift中实现从hashValue到hash(into:)的转换?

31

我对编译器发出的废弃警告,不再使用hashValue而是实现hash(into:),并没有很清楚的想法。

'Hashable.hashValue'已被弃用作为协议要求; 通过实现'hash(into:)'将类型'MenuItem'符合'Hashable'

Swift: 'Hashable.hashValue' is deprecated as a protocol requirement; 的答案有以下示例:

func hash(into hasher: inout Hasher) {
    switch self {
    case .mention: hasher.combine(-1)
    case .hashtag: hasher.combine(-2)
    case .url: hasher.combine(-3)
    case .custom(let regex): hasher.combine(regex) // assuming regex is a string, that already conforms to hashable
    }
}

我有这个结构体,可以自定义 Parchment 的 PagingItemhttps://github.com/rechsteiner/Parchment)。

import Foundation

/// The PagingItem for Menus.
struct MenuItem: PagingItem, Hashable, Comparable {
    let index: Int
    let title: String
    let menus: Menus

    var hashValue: Int {
        return index.hashValue &+ title.hashValue
    }

    func hash(into hasher: inout Hasher) {
        // Help here?
    }

    static func ==(lhs: MenuItem, rhs: MenuItem) -> Bool {
        return lhs.index == rhs.index && lhs.title == rhs.title
    }

    static func <(lhs: MenuItem, rhs: MenuItem) -> Bool {
        return lhs.index < rhs.index
    }
}

2个回答

62

你可以简单地使用hasher.combine,并用要用于哈希的值调用它:

func hash(into hasher: inout Hasher) {
    hasher.combine(index)
    hasher.combine(title)
}

8

对于hashValue的创建,有两个现代选项。

func hash(into hasher: inout Hasher) {
  hasher.combine(foo)
  hasher.combine(bar)
}

// or

// which is more robust as you refer to real properties of your type
func hash(into hasher: inout Hasher) {
  foo.hash(into: &hasher)
  bar.hash(into: &hasher)
}

2
请注意:combine(:)方法只是一个方便的操作,它接受一个可哈希的值,例如整数或字符串。在幕后,这个combine(:)方法调用hash(into:)方法将其值混合到Hasher状态中。 - Yasper

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接