Associated Values — mechanizm Swift, pozwalający na dołączenie dowolnych danych do każdego wariantu enum indywidualnie. W przeciwieństwie do raw values, gdzie wszystkie case'y mają wartości tego samego typu, associated values mogą różnić się typem i liczbą dla każdego case'a. Według Apple Documentation, 2026, jest to kluczowa możliwość precyzyjnego modelowania dziedziny bez tworzenia dodatkowych typów opakowujących.
Najważniejsze
Associated Values — to dodatkowe informacje, które case enum może przechowywać razem z sobą. W przeciwieństwie do raw values, które są ustalone na poziomie deklaracji, associated values są określane podczas tworzenia instancji enum.
Wyobraź sobie modelowanie metody płatności: case creditCard może przechowywać ostatnie 4 cyfry i datę ważności, a case applePay — nic. Dzięki associated values jest to realizowane naturalnie, bez podklas czy opcjonalnych pól.
Według dokumentacji Apple, associated values przekształcają enum z prostego zestawu stałych w algebraiczny typ danych (sum type), charakterystyczny dla języków funkcyjnych. Znacząco zwiększa to wyrazistość kodu.
Associated values są deklarowane w nawiasach okrągłych po case, z podaniem nazw i typów parametrów, jak w funkcjach.
enum MediaFile {
case image(width: Int, height: Int, format: String)
case video(duration: Double, codec: String)
case audio(bitrate: Int)
case unknown
}
Podczas tworzenia instancji associated values są przekazywane jako argumenty:
let photo = MediaFile.image(width: 1920, height: 1080, format: "jpeg")
let clip = MediaFile.video(duration: 120.5, codec: "h264")
Swift nie nakłada ograniczeń na liczbę ani typy associated values. Możesz używać dżeneryków, funkcji-zamykań i innych enum wewnątrz associated values. Umożliwia to budowanie złożonych zagnieżdżonych struktur.
Nazwy parametrów associated values są używane jako etykiety argumentów podczas tworzenia instancji — poprawia to czytelność kodu. Podczas wydobycia przez switch nazwy służą jako dokumentacja, wyjaśniając znaczenie każdej wartości. Takie podejście sprawia, że kod jest samodokumentujący się i zmniejsza prawdopodobieństwo błędów podczas dopasowywania danych. Jest to szczególnie cenne w zespołowym tworzeniu dużych aplikacji iOS.
Switch — główny sposób wydobywania associated values. Wartości są wiązane do stałych lub zmiennych przez let lub 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 obsługuje częściowe dopasowanie — można określać konkretne wartości associated values:
switch file {
case .image(let w, let h, "png"):
print("Obraz PNG \(w)x\(h)")
case .image(1920, 1080, _):
print("Obraz Full HD")
default:
break
}
Użycie wildcard (_) pozwala ignorować niepotrzebne associated values, a stałe w case'ach — sprawdzać zgodność z konkretnymi wartościami.
Wielu początkujących programistów myli associated values z raw values. To różne mechanizmy z różnymi scenariuszami zastosowania.
| Cecha | Raw Values | Associated Values |
|---|---|---|
| Typ danych | Jeden typ dla wszystkich case'ów | Różne typy dla każdego case'a |
| Moment określenia | Podczas deklaracji enum | Podczas tworzenia instancji |
| Obowiązkowość | Wszystkie case'y mają wartość | Niektóre case'y mogą być bez wartości |
| Zgodność | Wzajemnie wykluczające się — nie można używać jednocześnie | |
Według Swift Evolution, associated values zostały wprowadzone w Swift 2.0 jako część przeprojektowania enum. Zapewniają algebraiczne podejście do typów, gdzie każdy case to osobny konstruktor z własną sygnaturą.
Associated values są aktywnie wykorzystywane w rzeczywistych projektach iOS. Rozważmy trzy typowe scenariusze.
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)
}
Dzięki associated values enum zamienia się w potężne narzędzie dla automatów skończonych: każdy case to stan, associated values — parametry tego stanu. Kompilator gwarantuje, że wszystkie przejścia są obsłużone.
Do sprawdzenia jednego case'a bez switch użyj if case lub guard case. Jest to bardziej zwięzłe, gdy trzeba obsłużyć tylko jeden wariant.
let error = NetworkError.timeout(seconds: 30)
if case .timeout(let seconds) = error {
print("Żądanie przekroczyło limit czasu po \(seconds)s")
}
guard case .httpError(let code, _) = error else {
return
}
print("Błąd HTTP z kodem \(code)")
Często zadawane pytania
Tak, case może nie mieć associated values — na przykład case unknown. Takie case'y zachowują się jak zwykłe case'y enum bez dodatkowych danych. Jest to wygodne dla stanów znacznikowych.
Swift nie generuje Equatable automatycznie dla enum z associated values (przed Swift 4.2+). Dodaj jawną implementację Equatable lub użyj switch do porównywania każdego case'a po kolei.
Tak, associated values w indirect enum — standardowa technika do budowania drzew i list połączonych. Case może zawierać associated value tego samego typu z oznaczeniem indirect.
Associated values są bezpieczne typowo — każdy case gwarantowanie ma tylko swoje dane. W struct z opcjonalami każda instancja zawiera wszystkie pola i potrzebne są runtime'owe sprawdzenia na nil.
Swift nie generuje Codable automatycznie dla enum z associated values. Potrzebna jest ręczna implementacja encode i decode przez switch po case'ach z użyciem custom coding keys.
Podsumowanie
Opracujemy aplikację mobilną pod klucz
IT Sectr tworzy aplikacje na iOS i Androida dla startupów i firm od 2017 roku. Doradzimy Ci i zaproponujemy najlepsze rozwiązanie.
Przeczytaj również