Associated Values — механизм Swift, позволяющий привязать произвольные данные к каждому варианту enum индивидуально. В отличие от raw values, где все кейсы имеют однотипные значения, associated values могут различаться по типу и количеству для каждого кейса. По данным Apple Documentation, 2026, это ключевая возможность для точного моделирования предметной области без создания дополнительных типов-обёрток.
Главное
Associated Values — это дополнительная информация, которую enum-кейс может хранить вместе с собой. В отличие от raw values, которые фиксированы на уровне объявления, associated values задаются при создании экземпляра enum.
Представьте моделирование платёжного метода: кейс creditCard может хранить последние 4 цифры и срок действия, а кейс applePay — ничего. С associated values это реализуется естественно, без подклассов или опциональных полей.
По данным документации Apple, associated values превращают enum из простого набора констант в алгебраический тип данных (sum type), характерный для функциональных языков. Это существенно повышает выразительность кода.
Associated values объявляются в круглых скобках после кейса, с указанием имён и типов параметров, как у функций.
enum MediaFile {
case image(width: Int, height: Int, format: String)
case video(duration: Double, codec: String)
case audio(bitrate: Int)
case unknown
}
При создании экземпляра associated values передаются как аргументы:
let photo = MediaFile.image(width: 1920, height: 1080, format: "jpeg")
let clip = MediaFile.video(duration: 120.5, codec: "h264")
Swift не накладывает ограничений на количество или типы associated values. Вы можете использовать дженерики, функции-замыкания и другие enum внутри associated values. Это делает возможным построение сложных вложенных структур.
Имена параметров associated values используются как метки аргументов при создании экземпляра — это улучшает читаемость кода. При извлечении через switch имена служат документацией, поясняя смысл каждого значения. Такой подход делает код самодокументируемым и снижает вероятность ошибок при сопоставлении данных. Это особенно ценно в командной разработке крупных iOS-приложений.
Switch — основной способ извлечения associated values. Значения привязываются к константам или переменным через let или var.
func describe(_ file: MediaFile) -> String {
switch file {
case .image(let w, let h, let fmt):
return "Image \(w)x\(h) .\(fmt)"
case .video(let duration, let codec):
return "Video \(duration)s, \(codec)"
case .audio(let bitrate):
return "Audio \(bitrate)kbps"
case .unknown:
return "Unknown format"
}
}
Swift поддерживает частичное сопоставление — можно указывать конкретные значения associated values:
switch file {
case .image(let w, let h, "png"):
print("PNG image \(w)x\(h)")
case .image(1920, 1080, _):
print("Full HD image")
default:
break
}
Использование wildcard (_) позволяет игнорировать ненужные associated values, а константы в кейсах — проверять на совпадение с конкретными значениями.
Многие начинающие разработчики путают associated values с raw values. Это разные механизмы с разными сценариями применения.
| Характеристика | Raw Values | Associated Values |
|---|---|---|
| Тип данных | Один тип для всех кейсов | Разные типы для каждого кейса |
| Момент задания | При объявлении enum | При создании экземпляра |
| Обязательность | Все кейсы имеют значение | Некоторые кейсы могут быть без значений |
| Совместимость | Взаимоисключающие — нельзя использовать одновременно | |
По данным Swift Evolution, associated values были введены в Swift 2.0 как часть редизайна enum. Они обеспечивают алгебраический подход к типам, где каждый кейс — отдельный конструктор с собственной сигнатурой.
Associated values активно применяются в реальных iOS-проектах. Рассмотрим три типовых сценария.
enum APIResponse<T: Codable> {
case success(data: T, cached: Bool)
case failure(error: Error, retryAvailable: Bool)
case loading(progress: Double)
}
enum ViewState<T> {
case idle
case loading(message: String)
case loaded(data: T)
case error(message: String, retryAction: () -> Void)
}
С associated values enum превращается в мощный инструмент для конечных автоматов: каждый кейс — состояние, associated values — параметры этого состояния. Компилятор гарантирует, что все переходы обработаны.
Для проверки одного кейса без switch используйте if case или guard case. Это компактнее, когда нужно обработать только один вариант.
let error = NetworkError.timeout(seconds: 30)
if case .timeout(let seconds) = error {
print("Request timed out after \(seconds)s")
}
guard case .httpError(let code, _) = error else {
return
}
print("HTTP error with code \(code)")
Часто задаваемые вопросы
Да, кейс может не иметь associated values — например, case unknown. Такие кейсы ведут себя как обычные enum-кейсы без дополнительных данных. Это удобно для маркерных состояний.
Swift не генерирует Equatable автоматически для enum с associated values (до Swift 4.2+). Добавьте явную реализацию Equatable или используйте switch для поочередного сравнения каждого кейса.
Да, associated values в indirect enum — стандартный приём для построения деревьев и связанных списков. Кейс может содержать associated value того же типа с пометкой indirect.
Associated values типобезопасны — каждый кейс гарантированно имеет только свои данные. В struct с опционалами любой экземпляр содержит все поля, и нужны runtime-проверки на nil.
Swift не генерирует Codable автоматически для enum с associated values. Нужна ручная реализация encode и decode через switch по кейсам с использованием custom coding keys.
Итоги
Мы разработаем мобильное приложение под ключ
IT Sectr создаёт приложения для iOS и Android для стартапов и бизнеса с 2017 года. Мы проконсультируем вас и предложим наилучшее решение.
Читайте также