Легко сопоставляйте случаи перечисления, извлекайте связанные с ними значения, трансформируйте их и т. Д. С помощью 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, просто убедитесь, что у вас есть случаи перечисления с уникальными именами без закрытий в качестве параметров.