Можно ли автоматически генерировать (и обновлять) реализацию Hashable в Swift?
В Java можно автоматически генерировать реализации toString()
, hashCode()
, а также equals(Object)
, для объектов значения, использующих библиотеку AutoValue. Преимущества заключаются в том, что эти методы автоматически обновляются при добавлении новых полей. У меня вопрос, есть ли эквивалентная функциональность, доступная для Swift (встроенная или в виде библиотеки)?
пример
Простой пример, демонстрирующий текущую ситуацию в Swift. Рассмотрим следующую структуру:
struct PlainStruct {
let a:String
let b:Int
let c:Double
}
Чтобы оно соответствовало Hashable
Я изменил это следующим образом:
struct HashableStruct : Hashable {
let a:String
let b:Int
let c:Double
var hashValue: Int {
return 5381 &+ a.hashValue &+ b.hashValue &+ c.hashValue
}
static func ==(lhs: HashableStruct, rhs: HashableStruct) -> Bool {
return lhs.a == rhs.a
&& lhs.b == rhs.b
&& lhs.c == rhs.c
}
}
Добавленный код, хотя и простой, создает дополнительную нагрузку для программистов, особенно когда программное обеспечение продолжает развиваться (как это обычно происходит). В идеале я хотел бы иметь возможность просто добавить атрибут (например, аннотацию в Java) в структуру:
@autovalue
struct HashableStruct : Hashable {
let a:String
let b:Int
let c:Double
}
В настоящее время это невозможно, поскольку в Swift нет способа указать пользовательские атрибуты. Есть ли другой способ реализовать это в Swift?
Мотивация для AutoValue в Java
Следующий текст взят со страницы AutoValue, он мотивирует, почему AutoValue был создан. Я ожидаю, что те же рассуждения применимы в контексте Swift, но я не настолько опытен в Swift, как в Java, поэтому поправьте меня, если я ошибаюсь.
Классы значений чрезвычайно распространены в проектах Java. Это классы, для которых вы хотите обрабатывать любые два экземпляра с соответственно равными значениями полей как взаимозаменяемые. Правильно: мы говорим о тех классах, в которых вы реализуете equals, hashCode и toString раздутым, повторяющимся, формальным, но подверженным ошибкам способом.
Написание этих методов в первый раз не так уж плохо, с помощью нескольких вспомогательных методов и шаблонов IDE. Но после написания они продолжают обременять рецензентов, редакторов и будущих читателей. Их широкие простейшие шаблоны резко уменьшают отношение сигнал / шум в вашем коде... и им нравится скрывать трудно обнаруживаемые ошибки.
AutoValue предоставляет более простой способ создания классов с неизменяемыми значениями, с гораздо меньшим количеством кода и меньшим пространством для ошибок, не ограничивая при этом вашу свободу кодировать практически любой аспект вашего класса именно так, как вы этого хотите.