【问题标题】:why do i receive this warning to implement 'hash(into:)' on a type that conforms to a protocol with at default implementation为什么我会收到此警告以在符合默认实现的协议的类型上实现“hash(into:)”
【发布时间】:2020-11-13 11:29:46
【问题描述】:

下面的代码显示了警告:

 ❯ swiftc demo.swift                                                                                                                                                                       [13:06:57]
Swift.RawRepresentable:2:27: warning: 'Hashable.hashValue' is deprecated as a protocol requirement; conform type 'PlaybackSpeed' to 'Hashable' by implementing 'hash(into:)' instead
    @inlinable public var hashValue: Int { get }

枚举 PlaybackSpeed 应具有默认实现中的函数 resetSettings()hash(into:),因此不应生成此警告。

是我的理解错误还是编译器的错误?

protocol Settingsable {
  func resetSettings()
}

protocol SettingsSelectable: Hashable, Settingsable {
  var display: String { get }
}

extension SettingsSelectable {
  func hash(into hasher: inout Hasher) {
    hasher.combine(display)
  }
}

extension SettingsSelectable {
    func resetSettings() {
      print("These have been reset")
    }
}

enum PlaybackSpeed: Int, SettingsSelectable {
  case half
  case standard
  case onePointFive
  case double

  var display: String {
    switch self {
    case .half:
      return "0.5x"
    case .standard:
      return "1.0x"
    case .onePointFive:
      return "1.5x"
    case .double:
      return "2.0x"
    }
  }
}

【问题讨论】:

  • 带有警告的代码在哪里?
  • @Jessy 对我来说,这并没有在操场上产生警告,但是当我将它添加到项目中时(MacOS,Xcode 12.2,如果这是相关的)。

标签: swift hashable swift-compiler


【解决方案1】:

此代码有两个hash(into:) 的默认实现。一个来自 Int,一个来自 SettingSelectable。

我不确定这是否是已定义的行为。我的期望是使用 Int 实现并忽略 SettingsSelectable 扩展。无论如何,诊断不是很好。我建议opening a defect

您可以通过删除Int 或显式实现hash(into:) 来修复此错误,这样您的意思就很清楚了。或者您可以创建另一层协议:

protocol SettingsSelectableBase: Hashable, Settingsable {
  var display: String { get }
}

protocol SettingsSelectable: SettingsSelectableBase {}

// Only give the default to things that ask for it, not to Base conformers
extension SettingsSelectable {
  func hash(into hasher: inout Hasher) {
    hasher.combine(display)
  }
}

extension SettingsSelectableBase {
    func resetSettings() {
      print("These have been reset")
    }
}

enum PlaybackSpeed: Int, SettingsSelectableBase { ... }

【讨论】:

  • 打开 SR-13851 ,通过显式实现 hash(into:) 修复它
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-12-23
  • 1970-01-01
  • 2020-12-14
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多