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. يمكنك استخدام الأدوية (generics) ودوال الإغلاق و 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
}
يسمح استخدام حرف البدل (_) بتجاهل 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("انتهت مهلة الطلب بعد \(seconds)s")
}
guard case .httpError(let code, _) = error else {
return
}
print("خطأ HTTP بالرمز \(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 مع خيارات، يحتوي كل مثيل على جميع الحقول، وهناك حاجة لفحوصات nil في وقت التشغيل.
لا ينشئ Swift Codable تلقائيًا لـ enum مع associated values. يلزم تنفيذ يدوي لـ encode و decode عبر switch على الحالات باستخدام مفاتيح ترميز مخصصة.
الخلاصة
سنقوم بتطوير تطبيق جوال جاهز
تقدم IT Sectr تطبيقات iOS وAndroid للشركات الناشئة والشركات منذ عام 2017. سوف نقدم لك النصح ونقترح أفضل حل.