Введение и проблематика
Enumerations (enum) позволяют определить тип с фиксированным набором возможных значений. В Swift enum — это полноценный тип со своими методами и свойствами, а не просто набор констант как в C.
Swift enums — одни из самых мощных среди языков программирования. Они могут иметь associated values, raw values, методы и реализовывать протоколы.
Объявление enum
Базовый синтаксис
enum CompassDirection {
case north
case south
case east
case west
}
// Или в одну строку:
enum Planet {
case mercury, venus, earth, mars, jupiter, saturn, uranus, neptune
}
Создание экземпляра
var direction = CompassDirection.north
direction = .south // Тип уже известен, можно сократить
Использование с switch
❓
Code Example 1: Что выведет код?
enum TrafficLight {
case red
case yellow
case green
}
let light = TrafficLight.yellow
switch light {
case .red:
print("Stop")
case .yellow:
print("Caution")
case .green:
print("Go")
}
⚠️
Switch на enum должен быть exhaustive — покрывать все cases. Иначе нужен default.
С default
switch light {
case .red:
print("Stop")
default:
print("Proceed with caution")
}
Enum как тип
❓
Code Example 2: Скомпилируется ли этот код?
enum Size {
case small
case medium
case large
}
func printSize(_ size: Size) {
print("Size: \(size)")
}
printSize(.medium)
printSize(Size.large)
Методы в enum
enum Direction {
case up, down, left, right
func description() -> String {
switch self {
case .up: return "Moving up"
case .down: return "Moving down"
case .left: return "Moving left"
case .right: return "Moving right"
}
}
}
let move = Direction.up
print(move.description()) // "Moving up"
Mutating методы
enum Toggle {
case on
case off
mutating func toggle() {
self = (self == .on) ? .off : .on
}
}
var switch1 = Toggle.off
switch1.toggle()
print(switch1) // on
Computed Properties
enum Season {
case spring, summer, autumn, winter
var description: String {
switch self {
case .spring: return "🌸 Spring"
case .summer: return "☀️ Summer"
case .autumn: return "🍂 Autumn"
case .winter: return "❄️ Winter"
}
}
}
let currentSeason = Season.summer
print(currentSeason.description) // "☀️ Summer"
Итерация по всем cases
С протоколом CaseIterable:
❓
Code Example 3: Что выведет код?
enum Beverage: CaseIterable {
case coffee
case tea
case juice
}
print("Available drinks: \(Beverage.allCases.count)")
for drink in Beverage.allCases {
print(drink)
}
Практический пример
enum HTTPStatus {
case ok
case notFound
case serverError
case unauthorized
var code: Int {
switch self {
case .ok: return 200
case .notFound: return 404
case .serverError: return 500
case .unauthorized: return 401
}
}
var isSuccess: Bool {
return self == .ok
}
}
let status = HTTPStatus.ok
print("Code: \(status.code), Success: \(status.isSuccess)")
Сравнение enum
enum Priority {
case low
case medium
case high
}
let p1 = Priority.high
let p2 = Priority.high
let p3 = Priority.low
print(p1 == p2) // true
print(p1 == p3) // false
Вложенные enum
enum Device {
enum Phone {
case iPhone
case android
}
enum Computer {
case mac
case pc
}
case phone(Phone)
case computer(Computer)
}
let myDevice = Device.phone(.iPhone)
Enum vs Struct vs Class
| Аспект | Enum | Struct | Class |
|---|
| Фиксированные значения | ✅ | ❌ | ❌ |
| Value type | ✅ | ✅ | ❌ |
| Методы | ✅ | ✅ | ✅ |
| Наследование | ❌ | ❌ | ✅ |
| Stored properties | ❌ | ✅ | ✅ |
Вопросы интервьюера
Q: Чем enum в Swift отличается от enum в C?
В Swift enum — полноценный тип с методами, computed properties и возможностью реализовывать протоколы. В C это просто набор целочисленных констант.
Q: Почему switch на enum должен быть exhaustive?
Swift проверяет на этапе компиляции, что все cases обработаны. Это предотвращает ошибки при добавлении новых cases.
Q: Может ли enum хранить данные?
Да, через associated values (каждый case хранит свои данные) или raw values (общий тип для всех cases). Но stored properties — нет.
Q: Когда использовать enum вместо Bool?
Когда значений больше двух или когда названия .on/.off более выразительны, чем true/false.
Источники