Enum в Swift — это тип, объединяющий группу связанных значений под одним именем. В отличие от C и Objective-C, где enum — просто набор целочисленных констант, Swift предлагает first-class перечисления с associated values, raw values, методами и поддержкой протоколов. По данным Apple, 2026, enum — один из ключевых инструментов типобезопасного моделирования состояний в iOS-разработке.
Главное
Enum (перечисление) — это пользовательский тип данных, который объединяет конечный набор взаимоисключающих вариантов. В Swift enum — не просто числовые константы, а полноценный тип с собственной логикой.
Каждый вариант перечисления называется кейсом. В отличие от Objective-C, где enum сводится к целочисленному типу, Swift позволяет каждому кейсу хранить собственные данные и иметь методы.
По данным Apple, enum в Swift поддерживает дженерики, инициализаторы, вычисляемые свойства и реализацию протоколов — это делает его применимым для моделирования состояний, ошибок, опций и конечных автоматов.
Используйте enum везде, где нужно представить конечное множество взаимоисключающих вариантов: состояния экрана, типы ошибок, направления, опции фильтрации.
Enum объявляется ключевым словом enum с последующим именем и телом в фигурных скобках.
enum CompassDirection {
case north
case south
case east
case west
}
Кейсы можно объявлять в одну строку через запятую:
enum Planet {
case mercury, venus, earth, mars, jupiter, saturn, uranus, neptune
}
Для обращения к кейсу используется точечный синтаксис после известного типа:
let direction = CompassDirection.north
// Type is known — shorthand syntax is available:
var currentPlanet = .earth
После присвоения переменной известного enum-типа Swift автоматически выводит тип, и можно опускать имя перечисления при обращении к кейсам.
Raw Values — это значения одного типа, которые назначаются каждому кейсу enum. В отличие от associated values, raw values одинаковы по типу для всех кейсов и задаются при объявлении.
enum HTTPStatusCode: Int {
case ok = 200
case notFound = 404
case internalServerError = 500
}
let code = HTTPStatusCode.notFound
print(code.rawValue) // 404
Для целочисленных raw values 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 позволяют привязать разные типы данных к каждому кейсу перечисления индивидуально. В отличие от raw values, associated values могут различаться по типу и количеству.
enum NetworkError {
case timeout(seconds: Int)
case httpError(code: Int, message: String)
case noConnection
case unknown(error: Error)
}
При обработке через switch associated values извлекаются через привязку к переменным или константам:
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 — перечисление, кейсы которого ссылаются на сам тип enum. Такие кейсы помечаются ключевым словом indirect.
indirect enum LinkedList<T> {
case empty
case node(value: T, next: LinkedList<T>)
}
Ключевое слово indirect перед enum помечает все кейсы как рекурсивные. Альтернативно можно пометить indirect только конкретный кейс:
enum ArithmeticExpression {
case number(Int)
indirect case addition(ArithmeticExpression, ArithmeticExpression)
indirect case multiplication(ArithmeticExpression, ArithmeticExpression)
}
Swift использует indirect для хранения рекурсивных кейсов как ссылок (reference semantics) вместо значений — это позволяет избежать бесконечного размера enum на стеке. Рекурсивные enum широко применяются при построении деревьев, связанных списков и AST.
Enum может реализовывать протоколы так же, как структуры и классы. Это ключевая возможность протокол-ориентированного программирования в 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 — тип с произвольным набором свойств. Enum не может иметь stored properties, но поддерживает computed properties и методы.
Нет, enum не может одновременно иметь raw values и associated values. Raw values — это значения одного типа для всех кейсов, associated values — индивидуальные данные для каждого кейса. Эти механизмы взаимоисключающие.
Добавьте соответствие протоколу CaseIterable. Swift автоматически сгенерирует свойство allCases, возвращающее коллекцию всех кейсов в порядке объявления. Это удобно для итерации по всем вариантам.
Switch — наиболее безопасный способ, так как компилятор проверяет исчерпывающий перебор. Можно использовать if case для проверки одного кейса или == для enum без associated values.
Да, enum поддерживает дженерики: enum Result<T, E> { case success(T); case failure(E) }. Это позволяет создавать типобезопасные обобщённые конструкции для обработки успеха и ошибки.
Итоги
Мы разработаем мобильное приложение под ключ
IT Sectr создаёт приложения для iOS и Android для стартапов и бизнеса с 2017 года. Мы проконсультируем вас и предложим наилучшее решение.
Читайте также