Використання Xcode 7.3.1 та Swift 2.2
Незважаючи на те, що я погоджуюсь з Мартіном Р, і керівництво по стилю Рея Вендерліха добре вказує на те, що перелічення є кращими майже у всіх випадках використання, оскільки це чистий простір імен, є одне місце, де використовують struct
козирі enums
.
Переключити оператори
Почнемо з версії struct:
struct StaticVars {
static let someString = "someString"
}
switch "someString" {
case StaticVars.someString: print("Matched StaticVars.someString")
default: print("Didn't match StaticVars.someString")
}
Використовуючи структуру, це збігатиметься та роздруковуватиметься Matched StaticVars.someString
.
Тепер давайте розглянемо версію enum без випадків (змінивши лише ключове слово struct
на enum
):
enum StaticVars {
static let someString = "someString"
}
switch "someString" {
case StaticVars.someString: print("Matched StaticVars.someString")
default: print("Didn't match StaticVars.someString")
}
Ви помітите, що ви отримуєте помилку часу компіляції в операторі switch на case StaticVars.someString:
рядку. Помилка Enum case 'someString' not found in type 'String'
.
Існує псевдо-обхідний шлях шляхом перетворення властивості static у закриття, яке замість цього повертає тип.
Тож ви б змінили це так:
enum StaticVars {
static let someString = { return "someString" }
}
switch "someString" {
case StaticVars.someString(): print("Matched StaticVars.someString")
default: print("Didn't match StaticVars.someString")
}
Зверніть увагу на необхідність дужок у заяві case, оскільки це тепер функція.
Недоліком є те, що тепер, коли ми зробили її функцією, вона виконується кожного разу, коли її викликають. Отже, якщо це просто простий примітивний тип, наприклад, String
або Int
, це не так вже й погано. По суті, це обчислювана властивість. Якщо це константа, яку потрібно обчислити, і ви хочете обчислити її лише один раз, розгляньте можливість обчислити її в іншу властивість і повернути це вже обчислене значення в закритті.
Ви також можете замінити ініціалізатор за замовчуванням на приватний, і тоді ви отримаєте такий самий тип помилки часу компіляції, як і у випадку безперечкового перерахування.
struct StaticVars {
static let someString = "someString"
private init() {}
}
Але з цим ви хочете помістити декларацію структури у власний файл, тому що якщо ви оголосите її в тому ж файлі, що, скажімо, клас View Controller, файл цього класу все одно зможе випадково створити екземпляр марного екземпляр StaticVars
, але поза файлом класу він буде працювати за призначенням. Але це ваш дзвінок.