【问题标题】:How can I update this Hashable.hashValue to conform to new requirements.?如何更新此 Hashable.hashValue 以符合新要求。?
【发布时间】:2019-08-26 06:12:45
【问题描述】:

我正在尝试修复 RayWenderlich 网站上不再受支持的旧教程。 警告出现在三个文件中,Chain.swift、Cookie.swift 和 Swap.swift 来自“如何使用 SpriteKit 和 Swift 制作类似于 Candy Crush 的游戏:”教程

即使在浏览了许多地方出现的可用回复之后,我也不知所措。我正在努力理解这段代码在做什么,以便我可以修复它。我知道这只是一个警告,我可能会忽略它,但游戏也会在应该出现空白图块的地方显示 X,所以我怀疑它可能与此有关?

警告是这样的:

'Hashable.hashValue' is deprecated as a protocol requirement; conform type 'Chain' to 'Hashable' by implementing 'hash(into:)' instead

文件示例

  class Chain: Hashable, CustomStringConvertible {
  var cookies: [Cookie] = []
  var score = 0

  enum ChainType: CustomStringConvertible {
    case horizontal
    case vertical

    var description: String {
      switch self {
      case .horizontal: return "Horizontal"
      case .vertical: return "Vertical"
      }
    }
  }

  var chainType: ChainType
  init(chainType: ChainType) {
    self.chainType = chainType
  }

  func add(cookie: Cookie) {
    cookies.append(cookie)
  }

  func firstCookie() -> Cookie {
    return cookies[0]
  }

  func lastCookie() -> Cookie {
    return cookies[cookies.count - 1]
  }

  var length: Int {
    return cookies.count
  }

  var description: String {
    return "type:\(chainType) cookies:\(cookies)"
  }

  var hashValue: Int {
    return cookies.reduce (0) { $0.hashValue ^ $1.hashValue }
  }

  static func ==(lhs: Chain, rhs: Chain) -> Bool {
    return lhs.cookies == rhs.cookies
  }
}

【问题讨论】:

  • 我看到了。对不起,没有帮助。 Apple 文档更加晦涩难懂。
  • 背景:Hashable 不再要求符合类型的 hashValue: Int 描述自己,而是要求他们接受 Hasher,并将自己“混合”到其中(通过混合他们的领域)。以前人们很难为具有多个字段的对象导出良好的哈希值,通常会求助于 hack,例如对所有元素进行异或运算 (a ^ b ^ c),或者更糟糕的是,获取连接元素的字符串的字符串值 ("\(a)-\(b)-\(c)".hashValue)。现在,您只需告诉哈希器要哈希什么,它会使用适当的哈希算法代表您执行此操作。

标签: swift xcode hashable


【解决方案1】:

来自Hashable 文档:

散列一个值意味着将它的基本组成部分输入一个散列函数,由 Hasher 类型表示。基本组件是那些有助于 Equatable 类型实现的组件。两个相等的实例必须以相同的顺序在 hash(into:) 中将相同的值提供给 Hasher。

来自hash(into:) 文档:

用于散列的组件必须与您类型的 == 运算符实现中比较的组件相同。使用这些组件中的每一个调用 hasher.combine(_:)。

实现

static func ==(lhs: Chain, rhs: Chain) -> Bool {
    return lhs.cookies == rhs.cookies
}

表明cookies 是确定实例相等性的“基本组件”。因此

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

Hashable 要求的有效(且合理)实现。

【讨论】:

  • 好的,如果我添加该有效代码,只需添加它,该文件中的错误就会消失。但它仍然不起作用。当然。如果我使用如图所示的静态函数删除块,它会抱怨链。 “Chain”类型不符合“Equatable”协议
  • @HarryMcGovern:为什么你删除了static func ==
  • 谢谢,这部分现在似乎工作了。我需要发布一个与本教程相关的新问题。
  • 好的,它又出现在游戏中。 var 值 = topLeft.hashValue 值 = 值 | topRight.hashValue
  • @HarryMcGovern:我不知道你在说什么,代码没有出现在你的问题中。我建议提出一个新问题(用一些独立的代码来证明问题)。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-12-16
  • 1970-01-01
  • 2019-08-19
  • 2011-04-09
  • 2021-06-04
  • 1970-01-01
相关资源
最近更新 更多