【问题标题】:Swift: 'Hashable.hashValue' is deprecated as a protocol requirement;Swift:“Hashable.hashValue”作为协议要求已被弃用;
【发布时间】:2019-08-19 01:59:24
【问题描述】:

我的 iOS 项目一直面临以下问题(这只是一个警告)。

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

  • Xcode 10.2
  • 斯威夫特 5

源代码:

public enum ActiveType {
    case mention
    case hashtag
    case url
    case custom(pattern: String)

    var pattern: String {
        switch self {
        case .mention: return RegexParser.mentionPattern
        case .hashtag: return RegexParser.hashtagPattern
        case .url: return RegexParser.urlPattern
        case .custom(let regex): return regex
        }
    }
}

extension ActiveType: Hashable, Equatable {
    public var hashValue: Int {
        switch self {
        case .mention: return -1
        case .hashtag: return -2
        case .url: return -3
        case .custom(let regex): return regex.hashValue
        }
    }
}

有更好的解决方案吗?警告本身建议我实施 'hash(into:)' 但我不知道,如何?

参考:ActiveLabel

【问题讨论】:

  • 看到这个寻求帮助:hashable-enhancements
  • 一开始为什么要覆盖hashValue?编译器可以自动为您的enum 合成Hashable 一致性。您也不需要显式声明Equatable 一致性,因为Hashable 继承自Equatable,因此当您声明Hashable 一致性时,会为您合成Equatable 方法。
  • 背景:Hashable 不再要求符合类型的 hashValue: Int 描述自己,而是要求他们接受 Hasher,并将自己“混合”到其中(通过混合他们的领域)。以前,人们很难为具有多个字段的对象导出良好的哈希值,通常会求助于 hack,例如对所有元素进行异或运算 (a ^ b ^ c),或者更糟糕的是,获取连接元素的字符串的字符串值 ("\(a)-\(b)-\(c)".hashValue)。现在,您只需告诉散列器要散列什么,它会使用适当的散列算法代表您执行此操作。

标签: swift hashable swift5


【解决方案1】:

正如警告所说,现在您应该实现 hash(into:) 函数。

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
    }
}

删除自定义hash(into:) 实现(除非您需要特定实现)会更好(在枚举和结构的情况下),因为编译器会自动为您合成它。

只要让你的枚举符合它:

public enum ActiveType: Hashable {
    case mention
    case hashtag
    case url
    case custom(pattern: String)

    var pattern: String {
        switch self {
        case .mention: return RegexParser.mentionPattern
        case .hashtag: return RegexParser.hashtagPattern
        case .url: return RegexParser.urlPattern
        case .custom(let regex): return regex
        }
    }
}

【讨论】:

  • 如果你删除 hashable 作为一种类型(从扩展/类)你也可以摆脱警告
猜你喜欢
  • 2020-12-14
  • 1970-01-01
  • 2013-09-18
  • 1970-01-01
  • 2013-05-21
  • 1970-01-01
  • 2021-12-30
  • 1970-01-01
相关资源
最近更新 更多