Я создаю структуру, которая действует как String
, за исключением того, что она использует только скалярные значения Unicode UTF-32. Таким образом, это массив из UInt32
. (См. этот вопрос для получения дополнительной информации.)
Что я хочу сделать
Я хочу, чтобы использовать пользовательскую структуру ScalarString
как ключ в словаре. Например:
var suffixDictionary = [ScalarString: ScalarString]() // Unicode key, rendered glyph value
// populate dictionary
suffixDictionary[keyScalarString] = valueScalarString
// ...
// check if dictionary contains Unicode scalar string key
if let renderedSuffix = suffixDictionary[unicodeScalarString] {
// do something with value
}
Проблема
Чтобы сделать это, ScalarString
необходимо реализовать Hashable Protocol. Я думал, что смогу сделать что-то вроде этого:
struct ScalarString: Hashable {
private var scalarArray: [UInt32] = []
var hashValue : Int {
get {
return self.scalarArray.hashValue // error
}
}
}
func ==(left: ScalarString, right: ScalarString) -> Bool {
return left.hashValue == right.hashValue
}
но затем я обнаружил, что массивы Swift не имеют hashValue
.
Что я читал
- Свойство объекта (массив не имеет
hashValue
) - Свойство ID (не уверен, как это можно было бы реализовать хорошо)
- Формула (похоже, любая формула для строки из 32-битных целых чисел будет тяжелой для процессора и имеет много целых переполнений)
- ObjectIdentifier (я использую структуру, а не класс)
- Наследование из NSObject (я использую структуру, а не класс)
Вот некоторые другие вещи, которые я читал:
- Внедрение Swift Hashable Protocol
- Быстрые протоколы сравнения
- Идеальная хэш-функция
- Членство в пользовательских объектах в Swift Массивы и словари
- Как реализовать Hashable для вашего настраиваемого класса
- Написание хорошей реализации Hashable в Swift
Вопрос
Swift Strings имеют свойство hashValue
, поэтому я знаю, что это возможно.
Как создать hashValue
для моей пользовательской структуры?
Обновления
Обновление 1: Я хотел бы сделать что-то, что не связано с преобразованием в String
, а затем с помощью String
hashValue
. Весь смысл создания моей собственной структуры состоял в том, чтобы я мог избежать большого количества преобразований String
. String
получает его hashValue
откуда-то. Кажется, я мог получить его, используя тот же метод.
Обновление 2: Я изучаю реализацию алгоритмов хеш-кодов строк из других контекстов. Мне трудно понять, что лучше всего и выражать их в Свифте.
- Java
hashCode
алгоритм - C-алгоритмы
- хэш-функция для строки (SO вопрос и ответы в C)
- Хеширование учебника (Исследовательская группа визуализации Вирджинии Технология)
- Алгоритмы функции хеширования общего назначения
Обновление 3
Я бы предпочел не импортировать какие-либо внешние фреймворки, если это не рекомендуется для этих целей.
Я представил возможное решение, используя функцию хеша DJB.