Associated Values — مکانیزم Swift که امکان پیوست کردن دادههای دلخواه به هر گزینه enum را به صورت جداگانه فراهم میکند. بر خلاف raw values، که در آن همه caseها مقادیری از یک نوع دارند، associated values میتوانند از نظر نوع و تعداد برای هر case متفاوت باشند. به گفته Apple Documentation, 2026، این یک قابلیت کلیدی برای مدلسازی دقیق حوزه بدون ایجاد انواع wrapper اضافی است.
نکات اصلی
Associated Values — اطلاعات اضافی است که یک case enum میتواند همراه خود ذخیره کند. بر خلاف raw values که در سطح اعلان ثابت هستند، associated values هنگام ایجاد نمونه enum تعیین میشوند.
مدلسازی روش پرداخت را تصور کنید: case creditCard میتواند ۴ رقم آخر و تاریخ انقضا را ذخیره کند، و case applePay — هیچ چیز. با associated values این کار به طور طبیعی و بدون زیرکلاس یا فیلدهای اختیاری پیادهسازی میشود.
به گفته مستندات اپل، associated values enum را از یک مجموعه ساده از ثابتها به یک نوع داده جبری (sum type) تبدیل میکند که مشخصه زبانهای تابعی است. این کار بیانگری کد را به طور قابل توجهی افزایش میدهد.
Associated values در پرانتز بعد از case، با ذکر نام و نوع پارامترها، مانند توابع، اعلان میشوند.
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 اعمال نمیکند. شما میتوانید از جنریکها، توابع closure و 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 \(w)x\(h)")
case .image(1920, 1080, _):
print("تصویر Full HD")
default:
break
}
استفاده از wildcard (_) امکان نادیده گرفتن associated values غیرضروری را فراهم میکند، و ثابتها در caseها — بررسی تطابق با مقادیر خاص.
بسیاری از توسعهدهندگان مبتدی associated values را با raw values اشتباه میگیرند. اینها مکانیزمهای متفاوتی با سناریوهای کاربردی متفاوت هستند.
| ویژگی | Raw Values | Associated Values |
|---|---|---|
| نوع داده | یک نوع برای همه caseها | انواع متفاوت برای هر case |
| زمان تعیین | هنگام اعلان enum | هنگام ایجاد نمونه |
| اجباری بودن | همه caseها مقدار دارند | برخی caseها میتوانند بدون مقدار باشند |
| سازگاری | انحصار متقابل — نمیتوان همزمان استفاده کرد | |
به گفته Swift Evolution، associated values در Swift 2.0 به عنوان بخشی از بازطراحی enum معرفی شدند. آنها رویکرد جبری به انواع را ارائه میدهند، که در آن هر case یک سازنده مجزا با امضای خاص خود است.
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 به ابزاری قدرتمند برای ماشینهای حالت متناهی تبدیل میشود: هر case یک حالت، associated values — پارامترهای آن حالت. کامپایلر تضمین میکند که همه انتقالها پردازش شدهاند.
برای بررسی یک case بدون switch از if case یا guard case استفاده کنید. این زمانی که فقط یک گزینه باید پردازش شود، فشردهتر است.
let error = NetworkError.timeout(seconds: 30)
if case .timeout(let seconds) = error {
print("درخواست پس از \(seconds) ثانیه زمانش تمام شد")
}
guard case .httpError(let code, _) = error else {
return
}
print("خطای HTTP با کد \(code)")
سوالات متداول
بله، یک case میتواند associated values نداشته باشد — مثلاً case unknown. چنین caseهایی مانند caseهای معمولی enum بدون داده اضافی رفتار میکنند. این برای حالتهای نشانهگذار مناسب است.
Swift به طور خودکار Equatable را برای enum با associated values تولید نمیکند (تا Swift 4.2+). پیادهسازی صریح Equatable را اضافه کنید یا از switch برای مقایسه تکتک caseها استفاده کنید.
بله، associated values در indirect enum — روش استاندارد برای ساخت درختها و لیستهای پیوندی است. یک case میتواند associated value از همان نوع را با علامت indirect داشته باشد.
Associated values از نظر نوع ایمن هستند — هر case فقط دادههای مخصوص خود را دارد. در struct با optionals، هر نمونه شامل همه فیلدهاست و نیاز به بررسیهای runtime برای nil دارد.
Swift به طور خودکار Codable را برای enum با associated values تولید نمیکند. پیادهسازی دستی encode و decode از طریق switch روی caseها با استفاده از custom coding keys لازم است.
خلاصه
ما یک اپلیکیشن موبایل به صورت کلید در دست توسعه خواهیم داد
IT Sectr از سال 2017 برنامههای iOS و Android را برای استارتاپها و کسبوکارها ایجاد میکند. ما به شما مشاوره میدهیم و بهترین راهحل را پیشنهاد خواهیم کرد.