iOS Mobile Инженер

iOS Mobile Инженер

Роадмап навыков для прокачки

Объявление и использование enum

SwiftТипыПеречисления

Основная идея

Enum в Swift — это first-class тип для группировки связанных значений. В отличие от многих языков, Swift enums могут иметь методы, computed properties и associated values, делая их мощным инструментом моделирования.

Ключевые аспекты

  • case — определяет возможные значения enum
  • Value type — enum копируется при присваивании
  • Exhaustive switch — switch должен покрывать все cases
  • Methods — enum может иметь методы
  • Associated values — данные, связанные с case (рассматриваются на j2)

Синтаксис

swift
enum Direction {
    case north
    case south
    case east
    case west
}
 
let heading = Direction.north

Использование в switch

swift
switch heading {
case .north: print("Going north")
case .south: print("Going south")
case .east: print("Going east")
case .west: print("Going west")
}

Частые ошибки на собеседованиях

  • Забывают, что switch должен быть exhaustive
  • Не знают, что enum может иметь методы
  • Путают с enum в C (в Swift это полноценный тип)
  • Не понимают разницу между enum и struct

Введение и проблематика

Enumerations (enum) позволяют определить тип с фиксированным набором возможных значений. В Swift enum — это полноценный тип со своими методами и свойствами, а не просто набор констант как в C.

Swift enums — одни из самых мощных среди языков программирования. Они могут иметь associated values, raw values, методы и реализовывать протоколы.


Объявление enum

Базовый синтаксис

swift
enum CompassDirection {
    case north
    case south
    case east
    case west
}
 
// Или в одну строку:
enum Planet {
    case mercury, venus, earth, mars, jupiter, saturn, uranus, neptune
}

Создание экземпляра

swift
var direction = CompassDirection.north
direction = .south  // Тип уже известен, можно сократить

Использование с switch

Code Example 1: Что выведет код?

swift
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

swift
switch light {
case .red:
    print("Stop")
default:
    print("Proceed with caution")
}

Enum как тип

Code Example 2: Скомпилируется ли этот код?

swift
enum Size {
    case small
    case medium
    case large
}
 
func printSize(_ size: Size) {
    print("Size: \(size)")
}
 
printSize(.medium)
printSize(Size.large)

Методы в enum

swift
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 методы

swift
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

swift
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: Что выведет код?

swift
enum Beverage: CaseIterable {
    case coffee
    case tea
    case juice
}
 
print("Available drinks: \(Beverage.allCases.count)")
 
for drink in Beverage.allCases {
    print(drink)
}

Практический пример

swift
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

swift
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

swift
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

АспектEnumStructClass
Фиксированные значения
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.


Источники

Code Example 1: Switch на enum

❓ Что выведет код?

swift
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")
}

Code Example 2: Enum как параметр функции

❓ Скомпилируется ли этот код?

swift
enum Size {
    case small
    case medium
    case large
}
 
func printSize(_ size: Size) {
    print("Size: \(size)")
}
 
printSize(.medium)
printSize(Size.large)

Code Example 3: CaseIterable

❓ Что выведет код?

swift
enum Beverage: CaseIterable {
    case coffee
    case tea
    case juice
}
 
print("Available drinks: \(Beverage.allCases.count)")
 
for drink in Beverage.allCases {
    print(drink)
}