Комментарии 17
ИМХО, стоило эти вещи оставить отдельно: перечисления — как низкоуровневая конструкция, совместимая с int, варианты — как алгебраический тип данных («тип-сумма») со всеми фичами, присущими такому типу.
В C и C++ так делают,
И? Надо смотреть на преимущества, а не просто повторять. Иначе зачем вообще нужен Swift — можно дальше на С или С++ писать.
Ну и в С++ "по стандарту" не (обязательно) int — это деталь реализации. Более того, тип можно и самому задать.
Насчёт невозможности приводить — это далеко не всегда нужно. За Swift не скажу, зато могу сказать за Rust, где enumы похожим образом выглядят. Там можно указать repr© — тогда (если это возможно) такой enum будет совместим с C.
Приведу вот такой пример. Можно отказаться от разнообразных числовых типов (int, short, long, unsigned int, float, double и т.д.) и перейти к единому числовому типу, скажем «numeric». Неограниченной длины, любой точности. Возможно это будет удобно. Но это будет сущность более сложная чем базовые типы, и безусловно, отказ от базовых типов уменьшит хакерскую мощь языка. Но в то же время добавление высокоуровневых вариантов с сохранением низкоуровневых перечислений не только не уменьшит, но и увеличит хакерские возможности языка программирования.
Все тот-же пример:
Создается библиотека с открытым АПИ. В ней есть класс Payment и в ней реализованы: CashPayment, CardPayment, GiftPayment, PayPalPayment.
Если разработчик библиотеки хочет дать возможность сторонним разработчикам наследоваться от всех этих классов, то их стоит объявить `open`.
Если только от Payment то все будут `public`, а Payment `open`.
И чтобы закрыть полностью данную возможность, надо все объявить `public`.
То есть `public` позволяет наследовать внутри библиотеки, но не позволяет наследоваться за пределами библиотеки, а `open` позволяет наследоваться и внутри и за пределами.
Поэтому описанная проблема, имеет решение на Swift 3.0
Я думаю, пример в статье стоит рассматривать больше с «клиентской» стороны.
В предполагаемом мобильном приложении на языке Swift не будет никакой бизнес-логики, типа «Провести оплату». Т.е. наверняка будет какой-то вызов API для проведения оплаты, чтобы сервер провёл эту операцию, но реализовывать метод Execute()
на стороне клиента не придётся.
На стороне клиента придётся реализовывать ленту с историей проведенных операций оплаты, в которой должны содержаться сущности разного рода: Cash Payment
, Card Payment
, PayPal Payment
и другие. И в данной ситуации важным является именно то, как организовать модель данных, полученных от сервера, чтобы их можно было единообразно отобразить в единой ленте.
И перечисления в данной ситуации играют роль логических ограничений. Например, у сущности PaymentWithEnums
физически не может быть воплощения, в котором будет содержаться и срок истечения карты expirationDate
, и transactionAuthCode
.
Enums + Associated Values = Swift