пожалуйста, объясните использование хешируемого протокола с реализацией в swift. Apple определяет хэшируемый как «тип, который предоставляет целочисленное значение хеш-функции». Хорошо, но что такое хеш-значение?
Какая польза от хешируемого протокола в swift4?
Ответы (4)
Чтобы объект соответствовал Hashable, нам нужно предоставить свойство hashValue, которое будет возвращать уникальный, согласованный номер для каждого экземпляра. Протокол Hashable наследуется от Equatable, поэтому вам также может понадобиться реализовать функцию ==.
Примечание. Если два объекта сравниваются как равные с использованием ==, они также должны генерировать одно и то же значение хеш-функции, но обратное неверно — могут возникнуть коллизии хэшей.
До Swift 4.1 соответствие Hashable было сложным, поскольку вам нужно было вычислять свойство hashValue вручную. В Swift 4.1 это улучшилось, так что hashValue можно было синтезировать от вашего имени, если все свойства соответствуют Hashable . В Swift 4.2 представлена новая структура Hasher, которая предоставляет универсальную хеш-функцию со случайным заполнением, чтобы сделать нашу жизнь проще. Подробнее
Если объект соответствует протоколу hashable
, он должен иметь hashValue
, как вы упомянули. hashValue
можно использовать для сравнения объектов/уникальной идентификации объекта.
Вы можете сравнивать объекты двумя способами:
===
функция. Это проверяет ссылки на объекты (может использоваться только с классами). Он проверяет, имеет ли левый объект ту же ссылку на правый объект. Даже если оба объекта имеют одинаковые значения свойств, НО у них разные ссылки, он возвращает false.Функция
==
(протоколEquatable
). Он проверяет, равны ли объекты друг другу на основе статической функции==
. Вы можете вернутьhashValue
объекта. Таким образом, вы можете сказать, что объекты равны друг другу на основе свойств, а не ссылки.
Если вы предоставляете свои собственные hashValue
, вы можете сказать, что объекты равны друг другу таким же образом, как вы говорите, что объекты равны друг другу, независимо от ссылки на объект. Вы можете использовать объекты в Set
, которые соответствуют протоколу хеширования, потому что Set
проверяет, равны ли объекты друг другу на основе hashValue
.
Быстрый ответ:
Мы используем целочисленный хэш в объект, чтобы иметь возможность быстро идентифицировать объекты, которые равны, получая экземпляр объекта перед индексом, который мы ищем.
Не быстрый ответ:
Когда вы имеете дело со списком, чтобы найти объект, который вам нужно перебрать по всему массиву и сравнить свойство, чтобы найти тот, который вы ищете, это может замедлить работу вашего приложения по мере увеличения списка.
Когда вы используете SET, внутренний механизм использует хэш-индексы для поиска объекта, поэтому вам требуется только время для вычисления индекса, который вы ищете, а затем вы можете получить прямой доступ к своему объекту, ЭТО ТАК КРУТО НЕТ. Чтобы использовать SET, объект должен соответствовать протоколу Hashable, начиная с Swift 4.1, если ваш класс или структура и все свойства соответствуют протоколу Hashable, то соответствие протоколу Hashable и Equatable выполняется автоматически внутри вас. Если вы не соответствуете этим требованиям, вам придется убедиться, что вы соответствуете протоколу Equatable и Hashable.
Протокол Equatable должен переопределить статическую функцию ==(..), чтобы сравнить ваш объект.
Протокол Hashable должен предоставить, насколько это возможно, уникальное целочисленное значение hashValue, которое должно быть одинаковым в двух объектах, когда они равны. Надеюсь, это поможет
Hashable документация дает один конкретный пример того, для чего он нужен:
Вы можете использовать любой тип, соответствующий протоколу Hashable, в наборе или в качестве ключа словаря.
Вы можете думать о хеш-значении как о быстром приближении к равенству. Два одинаковых элемента будут иметь одинаковое хеш-значение, но два элемента с одинаковым хэш-значением не обязательно будут равными.