مقدمة إلى البرمجة الوظيفية في سويفت
سويفت هي لغة برمجة متعددة النماذج طورتها شركة أبل لإنشاء تطبيقات لأنظمة iOS وmacOS وwatchOS وtvOS. بالإضافة إلى الأساليب الكائنية والموجهة بالبروتوكولات، تدعم سويفت بنشاط البرمجة الوظيفية. يعتمد هذا الأسلوب على استخدام الدوال البحتة، وثبات البيانات، وتجنب الآثار الجانبية.
تجعل البرمجة الوظيفية الكود أكثر قابلية للتنبؤ والاختبار والأمان في التزامن. في هذه المقالة، سنقوم بتحليل المفاهيم الرئيسية للنهج الوظيفي في سويفت: الثبات، والدوال عالية المستوى، والإغلاقات، وسلاسل الدوال. سترى كيفية كتابة كود موجز ومعبّر باستخدام map وfilter وreduce.
أساسيات النهج الوظيفي في سويفت
الثبات
في البرمجة الوظيفية، لا يتم تعديل البيانات بعد إنشائها. بدلاً من تغيير كائن موجود، يتم إنشاء كائن جديد. تشجع سويفت هذا النهج باستخدام الكلمة المفتاحية let لتعريف الثوابت.
// قيمة غير قابلة للتغييرlet numbers = [1, 2, 3, 4, 5]// numbers.append(6) // خطأ في التجميع — numbers غير قابل للتغيير
// إنشاء مصفوفة جديدةlet newNumbers = numbers + [6]print(newNumbers) // [1, 2, 3, 4, 5, 6]استخدام let بدلاً من var يساعد في تجنب التغييرات غير المقصودة في الحالة ويبسط عملية التصحيح.
الدوال كمواطن من الدرجة الأولى
في سويفت، الدوال هي مواطن من الدرجة الأولى. يمكن تعيينها للمتغيرات، وتمريرها كوسيطات، وإرجاعها من دوال أخرى.
// دالة تم تعيينها لمتغيرlet multiply: (Int, Int) -> Int = { $0 * $1 }print(multiply(3, 4)) // 12
// دالة تأخذ دالة أخرىfunc applyOperation(_ a: Int, _ b: Int, operation: (Int, Int) -> Int) -> Int { return operation(a, b)}
let result = applyOperation(10, 5, operation: multiply)print(result) // 50الإغلاقات في سويفت
الإغلاقات هي كتل وظيفية مكتفية بذاتها يمكنها التقاط وتخزين مراجع للمتغيرات من السياق المحيط بها. في سويفت، تُستخدم الإغلاقات على نطاق واسع لاستدعاءات الإرجاع والتحويلات الوظيفية.
// إغلاق بسيطlet greeting = { (name: String) -> String in return "Hello, \(name)!"}print(greeting("World")) // Hello, World!
// صيغة مختصرة مع معاملاتlet numbers = [3, 1, 4, 1, 5, 9]let sorted = numbers.sorted { $0 < $1 }print(sorted) // [1, 1, 3, 4, 5, 9]تجعل الإغلاقات الكود موجزًا ومعبّرًا، خاصة عند العمل مع المجموعات.
الدوال عالية المستوى: map, filter, reduce
هذه هي الركائز الثلاث للبرمجة الوظيفية في سويفت. تسمح بمعالجة المصفوفات والقواميس والمجموعات الأخرى دون حلقات صريحة.
map — تحويل كل عنصر
تطبق طريقة map إغلاقًا على كل عنصر من عناصر المجموعة وتعيد مصفوفة جديدة بالنتائج.
let prices = [100, 200, 300, 400]let discounted = prices.map { $0 * 0.9 }print(discounted) // [90.0, 180.0, 270.0, 360.0]
// العمل مع السلاسل النصيةlet names = ["Anna", "Boris", "Victor"]let uppercased = names.map { $0.uppercased() }print(uppercased) // ["ANNA", "BORIS", "VICTOR"]filter — التحديد حسب الشرط
تعيد filter مصفوفة جديدة تحتوي فقط على العناصر التي تستوفي شرطًا معينًا.
let scores = [45, 78, 92, 33, 88, 61]let passingScores = scores.filter { $0 >= 60 }print(passingScores) // [78, 92, 88, 61]
// تصفية السلاسل النصيةlet words = ["Swift", "iOS", "macOS", "function"]let shortWords = words.filter { $0.count <= 4 }print(shortWords) // ["iOS", "macOS"]