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 — еднакви стойности от един тип за всички case-ове на изброяването
  • Associated values — различни типове данни, прикачени към всеки case индивидуално
  • Case-овете се декларират с ключовата дума case и могат да съдържат методи
  • Switch с enum изисква изчерпателно покритие на всички варианти от компилатора

Какво е enum в Swift?

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

Всеки вариант на изброяването се нарича case. За разлика от Objective-C, където enum се свежда до целочислен тип, Swift позволява на всеки case да съхранява собствени данни и да има методи.

Според Apple, enum в Swift поддържа generics, инициализатори, изчисляеми свойства и имплементация на протоколи — това го прави приложим за моделиране на състояния, грешки, опции и крайни автомати.

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

Синтаксис на декларация на enum

Enum се декларира с ключовата дума enum, последвана от име и тяло в големи скоби.

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

Case-овете могат да се декларират на един ред със запетая:

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

За достъп до case се използва точков синтаксис след известния тип:

swift
let direction = CompassDirection.north
// Типът е известен — налична е съкратена нотация:
var currentPlanet = .earth

След присвояване на променлива от известен enum тип, Swift автоматично извежда типа и името на изброяването може да се пропусне при достъп до case-овете.

Raw Values в изброяванията

Raw Values — са стойности от един тип, които се присвояват на всеки case от enum. За разлика от associated values, raw values са еднакви по тип за всички case-ове и се задават при декларация.

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 позволяват прикачване на различни типове данни към всеки case от изброяването индивидуално. За разлика от 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 след \(seconds)s")
case .httpError(let code, let message):
    print("HTTP \(code): \(message)")
case .noConnection:
    print("Няма връзка")
case .unknown(let err):
    print("Неизвестно: \(err.localizedDescription)")
}

Според документацията на Apple, associated values правят enum изразителен инструмент за моделиране на сложни състояния без създаване на отделни типове-обвивки. Използвайте ги за сценарии като Result и моделиране на грешки с контекст.

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

Рекурсивен enum — изброяване, чиито case-ове се отнасят към самия тип enum. Такива case-ове се маркират с ключовата дума indirect.

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

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

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

Swift използва indirect за съхраняване на рекурсивни case-ове като референции (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 за автоматично генериране на колекция от всички case-ове или 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 са стойности от един тип за всички case-ове, associated values са индивидуални данни за всеки case. Тези механизми се взаимно изключват.

Как да получим масив от всички case-ове на enum?

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

Задължително ли е използването на switch за обработка на enum?

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

Може ли да се създаде enum с generics?

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

Резюме

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

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

IT Sectr създава iOS и Android приложения за стартъпи и бизнеси от 2017 г. Ще ви консултираме и ще предложим най-доброто решение.

Обсъдете проекта

Прочетете също