Как я могу обновить это Hashable.hashValue, чтобы соответствовать новым требованиям.? - PullRequest
1 голос
/ 04 апреля 2019

Я пытаюсь исправить старый учебник с сайта RayWenderlich, больше не поддерживается.Предупреждение появляется в трех файлах, Chain.swift, Cookie.swift и Swap.swift из учебника «Как сделать игру похожей на Candy Crush с помощью SpriteKit и Swift:», учебник

Я в растерянности даже после того, какизучение доступных ответов, которые появляются во многих местах.Я изо всех сил пытаюсь понять, что делает этот код, чтобы я мог это исправить.Я знаю, что это просто предупреждение, и я, вероятно, могу игнорировать его, но игра также показывает 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
  }
}

Ответы [ 2 ]

2 голосов
/ 04 апреля 2019

Из документации Hashable :

Хеширование значения означает передачу его основных компонентов в хеш-функцию, представленную типом Hasher.Основными компонентами являются те, которые способствуют реализации типа Equatable.Два равных экземпляра должны передавать одинаковые значения 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.

1 голос
/ 29 апреля 2019

Для того же примера: как объединить 2 условия, например,

func ==(lhs: Cookie, rhs: Cookie) -> Bool {
return lhs.column == rhs.column && lhs.row == rhs.row

}

Это не будет работать:

func hash(into hasher: inout Hasher) {
        hasher.combine(column) && hasher.combine(row)
    }

Но

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

будет все сравнивать?

Или даже более сложная функция для целочисленного сравнения:

func ==(lhs: SwapN, rhs: SwapN) -> Bool {
    if lhs.cookies.count != rhs.cookies.count {
        return false
    }

    for i in 0..<lhs.cookies.count {
        if lhs.cookies[i] != rhs.cookies[i] {
            return false
        }
    }
    return true
}

Как это должно быть передано?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...