В чем разница между raw value и associated value в Swift enum?

«В чем разница между raw value и associated value в Swift enum?» — вопрос из категории Swift Core, который задают на 10% собеседований IOS Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

В Swift перечисления (enum) могут хранить данные двумя способами: raw values (сырые значения) и associated values (ассоциированные значения). Их цели и применение различны.

Raw Value (Сырое значение)

  • Что это: Предопределенное, фиксированное значение, присвоенное каждому кейсу перечисления при его объявлении.
  • Тип: Все raw values в одном enum должны быть одного типа (String, Int, Character и т.д.).
  • Уникальность: Каждое значение должно быть уникальным в рамках enum.
  • Зачем: Чтобы enum мог быть инициализирован из своего raw value (init?(rawValue:)) и чтобы можно было получить raw value у существующего кейса (.rawValue). Часто используется для соответствия внешним данным (JSON, база данных).
// Каждому кейсу присвоено фиксированное String-значение
enum CompassDirection: String {
    case north = "N"
    case south = "S"
    case east = "E"
    case west = "W"
}

let direction = CompassDirection.north
print(direction.rawValue) // "N"
let newDirection = CompassDirection(rawValue: "S") // .south

Associated Value (Ассоциированное значение)

  • Что это: Дополнительные, переменные данные, которые можно прикрепить к конкретному экземпляру кейса при его создании.
  • Тип: Каждый кейс может иметь разные типы и количество ассоциированных значений.
  • Зачем: Чтобы хранить дополнительную информацию вместе с кейсом. Позволяет enum представлять более сложные типы данных (например, результат операции, который может быть успехом с данными или ошибкой).
// Кейсы хранят дополнительные данные разных типов
enum Barcode {
    case upc(Int, Int, Int, Int) // 4 числа
    case qrCode(String)           // 1 строка
}

let productCode = Barcode.upc(8, 85909, 51226, 3)
let siteCode = Barcode.qrCode("https://example.com")

// Доступ через switch
switch productCode {
case .upc(let numberSystem, let manufacturer, let product, let check):
    print("UPC: (numberSystem), (manufacturer), (product), (check)")
case .qrCode(let codeString):
    print("QR: (codeString)")
}

Итог: Raw value — это идентификатор кейса, а Associated value — это полезная нагрузка (payload) кейса.