Достаточно ли автосоответствия?
Видеоверсия этой статьи доступна по адресу https://youtu.be/h-xlW1pEBGI.
Элементы в наборе или словаре должны соответствовать Hashable
Обычно это означает, что нам нужно убедиться, что наш тип соответствует Hashable
. В этом примере мы собираемся поместить в набор простое животное struct
. Если мы не заявляем о соответствии Hashable
Swift, мы получаем довольно обнадеживающую ошибку:
однако компилятор может дать нам автоматическое Hashaable
соответствие, мы говорим компилятору, что нам требуется Hashable
соответствие (как и мы, чтобы поместить экземпляры struct
в набор). Это похоже на следующий фрагмент кода:
struct Animal: Hashable { let animalName: String } let dog = Animal(animalName: "dog") let cat = Animal(animalName: "cat") let animalSet: Set<Animal> = [dog, cat]
Поскольку свойство String
по умолчанию соответствует Hashable
, больше работать не нужно (ознакомьтесь с этой статьей, чтобы узнать о работе, которая может потребоваться для более сложных типов, чтобы соответствовать протоколу Hashable).
Это абсолютно нормально. Но как насчет использования enum
? Мы могли бы сделать это, чтобы добавить типы в set
, что, конечно, немного иная ситуация. Однако для целей этой статьи это покажет суть:
enum Animal { case dog case cat } let animalSet: Set<Animal> = [.cat, .dog]
Разница здесь в том, что перечисление (enum
) получает Hashable
соответствие автоматически - вам даже не нужно объявлять, что enum
соответствует Hashable
! Потрясающий!
А как насчет связанных типов?
Мы могли бы добавить это в наш enum
, но мы не получаем автоматического соответствия:
enum Animal { case dog(breed: String) case cat(breed: String) } let animalSet: Set<Animal> = [.cat(breed: “moggy”), .dog(breed: “lab”)]
К счастью, поскольку связанное значение (в данном случае) Hashable
, поскольку они просто String
, мы можем (в этом случае) объявить соответствие Hashable
с той же легкостью, что и в struct
выше:
enum Animal: Hashable { case dog(breed: String) case cat(breed: String) } let animalSet: Set<Animal> = [.cat(breed: "moggy"), .dog(breed: "lab")]
Вывод
Очень заманчиво использовать компилятор для устранения ошибок в коде, и это избавляет вас от необходимости думать, чтобы быстро решать проблемы кода. Однако знание того, что происходит, когда мы получаем эти Hashable
ошибок, и то, как мы можем их решить, является ключом к быстрому созданию отличного кода.
Конечно, мы не должны перестать думать о нашем коде, и в случае enum
получить что-то «бесплатно» не означает, что мы не должны думать о том, что происходит под капотом.
Надеюсь, эта статья была вам полезна.
Если у вас есть вопросы, комментарии или предложения, пишите мне в Twitter.