Я создаю структуру, которая действует как 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.