Enum в Swift — что это, синтаксис и использование

Автор: IT Sectr Опубликовано: 2026-06-17 Время чтения: 6 мин

Enum в Swift — это тип, объединяющий группу связанных значений под одним именем. В отличие от C и Objective-C, где enum — просто набор целочисленных констант, Swift предлагает first-class перечисления с associated values, raw values, методами и поддержкой протоколов. По данным Apple, 2026, enum — один из ключевых инструментов типобезопасного моделирования состояний в iOS-разработке.

Главное

  • Enum — тип для группы связанных значений, обеспечивающий типобезопасность
  • Raw values — одинаковые значения одного типа для всех кейсов перечисления
  • Associated values — разные типы данных, привязанные к каждому кейсу индивидуально
  • Кейсы объявляются ключевым словом case и могут содержать методы
  • Switch с enum требует исчерпывающего перебора всех вариантов компилятором

Что такое enum в Swift?

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

Каждый вариант перечисления называется кейсом. В отличие от Objective-C, где enum сводится к целочисленному типу, Swift позволяет каждому кейсу хранить собственные данные и иметь методы.

По данным Apple, enum в Swift поддерживает дженерики, инициализаторы, вычисляемые свойства и реализацию протоколов — это делает его применимым для моделирования состояний, ошибок, опций и конечных автоматов.

Используйте enum везде, где нужно представить конечное множество взаимоисключающих вариантов: состояния экрана, типы ошибок, направления, опции фильтрации.

Синтаксис объявления enum

Enum объявляется ключевым словом enum с последующим именем и телом в фигурных скобках.

swift
enum CompassDirection {
    case north
    case south
    case east
    case west
}

Кейсы можно объявлять в одну строку через запятую:

swift
enum Planet {
    case mercury, venus, earth, mars, jupiter, saturn, uranus, neptune
}

Для обращения к кейсу используется точечный синтаксис после известного типа:

swift
let direction = CompassDirection.north
// Type is known — shorthand syntax is available:
var currentPlanet = .earth

После присвоения переменной известного enum-типа Swift автоматически выводит тип, и можно опускать имя перечисления при обращении к кейсам.

Raw Values в перечислениях

Raw Values — это значения одного типа, которые назначаются каждому кейсу enum. В отличие от associated values, raw values одинаковы по типу для всех кейсов и задаются при объявлении.

swift
enum HTTPStatusCode: Int {
    case ok = 200
    case notFound = 404
    case internalServerError = 500
}

let code = HTTPStatusCode.notFound
print(code.rawValue) // 404

Для целочисленных raw values Swift автоматически инкрементирует значения, если явно задан только первый:

swift
enum Status: Int {
    case pending = 1
    case active      // 2
    case completed   // 3
}

Raw values могут быть типов Int, String, Character или любого типа, соответствующего протоколу RawRepresentable. Swift автоматически генерирует инициализатор init? для создания enum из raw value — это удобно при парсинге данных из API.

Associated Values в enum

Associated Values позволяют привязать разные типы данных к каждому кейсу перечисления индивидуально. В отличие от raw values, associated values могут различаться по типу и количеству.

swift
enum NetworkError {
    case timeout(seconds: Int)
    case httpError(code: Int, message: String)
    case noConnection
    case unknown(error: Error)
}

При обработке через switch associated values извлекаются через привязку к переменным или константам:

swift
let error = NetworkError.httpError(code: 403, message: "Forbidden")

switch error {
case .timeout(let seconds):
    print("Timeout after \(seconds)s")
case .httpError(let code, let message):
    print("HTTP \(code): \(message)")
case .noConnection:
    print("No connection")
case .unknown(let err):
    print("Unknown: \(err.localizedDescription)")
}

По данным документации Apple, associated values делают enum выразительным инструментом для моделирования сложных состояний без создания отдельных типов-обёрток. Используйте их для Result-подобных сценариев и моделирования ошибок с контекстом.

Рекурсивные enum (indirect)

Рекурсивный enum — перечисление, кейсы которого ссылаются на сам тип enum. Такие кейсы помечаются ключевым словом indirect.

swift
indirect enum LinkedList<T> {
    case empty
    case node(value: T, next: LinkedList<T>)
}

Ключевое слово indirect перед enum помечает все кейсы как рекурсивные. Альтернативно можно пометить indirect только конкретный кейс:

swift
enum ArithmeticExpression {
    case number(Int)
    indirect case addition(ArithmeticExpression, ArithmeticExpression)
    indirect case multiplication(ArithmeticExpression, ArithmeticExpression)
}

Swift использует indirect для хранения рекурсивных кейсов как ссылок (reference semantics) вместо значений — это позволяет избежать бесконечного размера enum на стеке. Рекурсивные enum широко применяются при построении деревьев, связанных списков и AST.

Enum и протоколы

Enum может реализовывать протоколы так же, как структуры и классы. Это ключевая возможность протокол-ориентированного программирования в Swift.

swift
protocol Describable {
    var description: String { get }
}

enum PaymentMethod: Describable {
    case creditCard(last4: String)
    case applePay
    case bankTransfer

    var description: String {
        switch self {
        case .creditCard(let last4):
            return "Card ending in \(last4)"
        case .applePay:
            return "Apple Pay"
        case .bankTransfer:
            return "Bank Transfer"
        }
    }
}

Enum также может реализовывать протоколы Cocoa — например, CaseIterable для автоматической генерации коллекции всех кейсов или Codable для сериализации. Это делает enum универсальным строительным блоком в Swift-приложениях.

Часто задаваемые вопросы

Чем enum отличается от struct в Swift?

Enum — это тип с конечным набором взаимоисключающих вариантов, а struct — тип с произвольным набором свойств. Enum не может иметь stored properties, но поддерживает computed properties и методы.

Может ли enum иметь и raw values, и associated values одновременно?

Нет, enum не может одновременно иметь raw values и associated values. Raw values — это значения одного типа для всех кейсов, associated values — индивидуальные данные для каждого кейса. Эти механизмы взаимоисключающие.

Как получить массив всех кейсов enum?

Добавьте соответствие протоколу CaseIterable. Swift автоматически сгенерирует свойство allCases, возвращающее коллекцию всех кейсов в порядке объявления. Это удобно для итерации по всем вариантам.

Обязательно ли использовать switch для обработки enum?

Switch — наиболее безопасный способ, так как компилятор проверяет исчерпывающий перебор. Можно использовать if case для проверки одного кейса или == для enum без associated values.

Можно ли создать enum с дженериками?

Да, enum поддерживает дженерики: enum Result<T, E> { case success(T); case failure(E) }. Это позволяет создавать типобезопасные обобщённые конструкции для обработки успеха и ошибки.

Итоги

  • Enum в Swift — полноценный тип с поддержкой методов, дженериков и протоколов
  • Raw values позволяют задать одинаковые значения одного типа для всех кейсов
  • Associated values дают возможность привязать разные данные к каждому кейсу
  • Indirect кейсы необходимы для рекурсивных структур в enum
  • Протоколы могут быть реализованы enum — это основа POP в Swift
  • Switch с enum гарантирует исчерпывающую обработку на уровне компиляции
  • Используйте enum для моделирования конечных состояний и типобезопасных опций

Мы разработаем мобильное приложение под ключ

IT Sectr создаёт приложения для iOS и Android для стартапов и бизнеса с 2017 года. Мы проконсультируем вас и предложим наилучшее решение.

Обсудить проект

Читайте также