Associated Values — Swift-mechanizmus, amely lehetővé teszi tetszőleges adatok csatolását minden egyes enum-variánshoz egyedileg. Ellentétben a raw values-szal, ahol minden case azonos típusú értékekkel rendelkezik, az associated values típusban és mennyiségben is eltérhetnek case-enként. A Apple Documentation, 2026 szerint ez kulcsfontosságú képesség a tartomány pontos modellezéséhez további csomagoló típusok létrehozása nélkül.
Főbb pontok
Associated Values — további információk, amelyeket egy enum case tárolhat magával. Ellentétben a raw values-szal, amelyek deklarációs szinten rögzítettek, az associated values az enum példányának létrehozásakor kerülnek meghatározásra.
Képzelje el egy fizetési mód modellezését: a creditCard case tárolhatja az utolsó 4 számjegyet és a lejárati dátumot, a applePay case pedig — semmit. Associated values-szel ez természetesen megvalósítható, alosztályok vagy opcionális mezők nélkül.
Az Apple dokumentációja szerint az associated values átalakítja az enumot egy egyszerű konstanskészletből algebrai adattípussá (sum type), amely a funkcionális nyelvekre jellemző. Ez jelentősen növeli a kód kifejezőerejét.
Associated values a case után zárójelben kerülnek deklarálásra, a paraméterek nevének és típusának megadásával, mint a függvényeknél.
enum MediaFile {
case image(width: Int, height: Int, format: String)
case video(duration: Double, codec: String)
case audio(bitrate: Int)
case unknown
}
Példány létrehozásakor az associated values argumentumokként kerülnek átadásra:
let photo = MediaFile.image(width: 1920, height: 1080, format: "jpeg")
let clip = MediaFile.video(duration: 120.5, codec: "h264")
A Swift nem ír elő korlátozásokat az associated values számára vagy típusaira. Használhat generikusokat, closure függvényeket és más enumokat az associated values-en belül. Ez lehetővé teszi összetett beágyazott struktúrák felépítését.
Az associated values paraméternevei argumentumcímkeként szolgálnak példány létrehozásakor — ez javítja a kód olvashatóságát. Switch-en keresztüli kinyeréskor a nevek dokumentációként szolgálnak, magyarázva az egyes értékek jelentését. Ez az megközelítés öndokumentálóvá teszi a kódot és csökkenti a hibák valószínűségét az adatok illesztésekor. Ez különösen értékes nagy iOS-alkalmazások csapatban történő fejlesztésekor.
Switch — az associated values kinyerésének fő módja. Az értékek konstansokhoz vagy változókhoz kötődnek let vagy var segítségével.
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"
}
}
A Swift támogatja a részleges illesztést — megadhatók az associated values konkrét értékei:
switch file {
case .image(let w, let h, "png"):
print("PNG kép \(w)x\(h)")
case .image(1920, 1080, _):
print("Full HD kép")
default:
break
}
A wildcard (_) használata lehetővé teszi a felesleges associated values figyelmen kívül hagyását, a case-ekben lévő konstansok pedig — az adott értékekkel való egyezés ellenőrzését.
Sok kezdő fejlesztő összekeveri az associated values-t a raw values-szal. Ezek különböző mechanizmusok, különböző alkalmazási forgatókönyvekkel.
| Jellemző | Raw Values | Associated Values |
|---|---|---|
| Adattípus | Egy típus minden case-hez | Különböző típusok minden case-hez |
| Meghatározás ideje | Az enum deklarálásakor | A példány létrehozásakor |
| Kötelezőség | Minden case-nek van értéke | Néhány case lehet érték nélküli |
| Kompatibilitás | Kölcsönösen kizárják egymást — nem használhatók együtt | |
A Swift Evolution szerint az associated values a Swift 2.0-ban került bevezetésre az enum újratervezésének részeként. Algebrai megközelítést biztosítanak a típusokhoz, ahol minden case egy külön konstruktor saját aláírással.
Associated values aktívan használatosak valós iOS-projektekben. Vizsgáljunk meg három tipikus forgatókönyvet.
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-szel az enum hatékony eszközzé válik véges automatákhoz: minden case — egy állapot, associated values — az állapot paraméterei. A fordító garantálja, hogy minden átmenet feldolgozásra kerül.
Egyetlen case switch nélküli ellenőrzéséhez használja a if case vagy guard case kifejezéseket. Ez tömörebb, ha csak egy változatot kell feldolgozni.
let error = NetworkError.timeout(seconds: 30)
if case .timeout(let seconds) = error {
print("A kérés időtúllépés \(seconds)s után")
}
guard case .httpError(let code, _) = error else {
return
}
print("HTTP hiba \(code) kóddal")
Gyakran ismételt kérdések
Igen, egy case-nek nem lehet associated values — például case unknown. Az ilyen case-ek úgy viselkednek, mint a szokásos enum case-ek további adatok nélkül. Ez kényelmes marker állapotokhoz.
A Swift nem generál automatikusan Equatable-t az associated values-szel rendelkező enum-okhoz (Swift 4.2+ előtt). Adjon hozzá explicit Equatable implementációt, vagy használjon switch-t az egyes case-ek összehasonlításához.
Igen, az indirect enum-ban lévő associated values — szabványos technika fák és láncolt listák építésére. Egy case tartalmazhat azonos típusú associated value-t indirect jelöléssel.
Associated values típusbiztonságosak — minden case garantáltan csak a saját adatait tartalmazza. Az opcionális mezőkkel rendelkező struct-ban minden példány tartalmazza az összes mezőt, és futásidejű nil ellenőrzések szükségesek.
A Swift nem generál automatikusan Codable-t az associated values-szel rendelkező enum-okhoz. A encode és decode kézi implementációja szükséges switch segítségével a case-eken, custom coding keys használatával.
Összefoglaló
Kulcsrakész mobilalkalmazást fejlesztünk
Az IT Sectr 2017 óta készít iOS és Android alkalmazásokat induló vállalkozásoknak és vállalkozásoknak. Tanácsot adunk, és a legjobb megoldást javasoljuk.
Olvassa el is