Легко сопоставляйте случаи перечисления, извлекайте связанные с ними значения, трансформируйте их и т. Д. С помощью EnumKit
Перечисления в Swift очень мощные. Обладая сверхспособностью иметь связанные значения, перечисления позволили пользователям Swift создать целый новый класс вариантов использования.
Мы используем перечисления для выражения ошибок, событий, действий, входных и выходных данных. Тем не менее, получить доступ к ассоциированному значению случая перечисления не так просто, как получить доступ к переменной структуры или класса.
В MERLin мы используем перечисления для описания событий, которые могут произойти в модуле.
Я предлагаю вам прочитать Архитектура, управляемая событиями в iOS с MERLin для получения дополнительной информации о том, что такое события и модули в этом контексте, но пока я просто определю событие как:
Сообщение, отправляемое системой для уведомления слушателей об изменении состояния.
Сегодня мы знаем два способа доступа к значениям, связанным с перечислением:
- Использование операторов switch.
- Использование сопоставления с образцом.
Нет ничего плохого в использовании переключателя или сопоставления с образцом, но иногда в наших алгоритмах нас может интересовать один конкретный случай.
Наличие переключателя только с одним регистром и значением по умолчанию немного расстраивает, тогда сопоставление с образцом работает только в операторах if и guard. Оба эти паттерна уродливы в реактивном контексте и потенциально будут часто повторяться.
Предположим теперь, что в вашем алгоритме вы заинтересованы в проверке того, что событие не является rated
.
Эту проблему можно решить только с помощью переключателя, у которого есть все случаи, кроме исключенного. В этом случае сопоставление с образцом становится совершенно бесполезным, если только вы не довольны тем, что у вас есть пустое if со всей вашей логикой в else, потому что оно не возвращает логическое значение, которое мы можем отрицать.
В конкретном случае MovieDetailPageEvent
мы могли бы согласовать перечисление с Equatable
и иметь более приятный код, но это не всегда легко или возможно.
EnumKit - это очень легкая библиотека, которая нацелена на расширение возможностей перечислений с помощью функций для легкого доступа и преобразования связанных значений, сопоставления случаев перечисления и работы с коллекциями случаев перечисления.
Все, что вам нужно сделать, чтобы получить эту возможность, - это привести перечисления в соответствие с протоколом маркеров CaseAccessible
, который не имеет требований соответствия.
С CaseAccessible
извлечь связанное значение так же просто, как получить доступ к значению массива: event[case: MovieDetailPageEvent.rated]
.
Поскольку CaseAccessible
является протоколом, мы также можем писать расширения для лучшей поддержки перечислений в других структурах данных, таких как array, observable (RxSwift) и publisher (Combine).
EnumKit поставляется с расширением для Sequence
, распространяющимся на массивы функций enum case, таких как compactMap
, flatMap
, forEach
и filter
.
Расширение для Combine's Publisher
готово в ветке, а расширения для RxSwift доступны в RxEnumKit.
Давайте посмотрим, как наш предыдущий пример с наблюдаемым будет выглядеть с EnumKit.
EnumKit также предоставляет простой механизм для обновления связанного значения с помощью индекса.
Доступ к связанным значениям - это давно запрашиваемая функция Swift. Хотя может потребоваться некоторое время, чтобы согласовать способ включения этой функции в язык, EnumKit доступен сегодня на CocoaPods и SwiftPM.
Ограничения
К сожалению, EnumKit не идеален. Хотя он буквально на 100% протестирован, существуют ограничения на сопоставление с образцом и извлечение связанных значений, которые я хочу раскрыть здесь:
- Это плохо работает с перегруженными корпусами. В некоторых случаях сопоставление шаблонов с кейсами enum с тем же именем приведет к сбою Xcode.
- Связанные значения не могут содержать замыкания. Извлечение будет успешным, но использование извлеченного таким образом закрытия может привести к сбою.
Даже с этими ограничениями EnumKit значительно улучшает способ работы с перечислениями. Если вы работаете с CaseAccessible
, просто убедитесь, что у вас есть случаи перечисления с уникальными именами без закрытий в качестве параметров.