تمرير الدالة كمعامل في Kotlin: دليل شامل للمبتدئين

مدرب بايثون أونلاين للمبتدئين

تعلم Python بسهولة دون إرهاق نظري. حل مهام عملية مع التحقق التلقائي واكتب الكود مباشرة في المتصفح.

ابدأ الدورة

Kotlin: كيف تمرر دالة كمعامل؟ نشرح بالأمثلة

\n\n

مرحباً يا صديقي! إذا كنت قد كتبت بلغة Kotlin يوماً وتساءلت: "كيف يمكنني تمرير دالة كمعامل إلى دالة أخرى؟" — فقد وصلت إلى المكان الصحيح. هذا السؤال على Stack Overflow حصد آلاف المشاهدات، وهذا ليس مفاجئاً. البرمجة الوظيفية في Kotlin ليست مجرد ميزة عصرية، بل أداة قوية تجعل الكود أنظف وأقصر وأكثر تعبيراً.

\n\n

في هذه المقالة، لن نقدم إجابة جافة فقط. سنشرح كل شيء من تعبيرات لامدا البسيطة إلى التقنيات المتقدمة. ستتعلم كيفية استخدام أنواع Function، وعامل الإشارة إلى الدالة ::، وحتى كيفية تجنب الأخطاء الشائعة للمبتدئين. هيا بنا!

\n\n

لماذا هذا مهم؟ ثلاثة أسباب لاستخدام الدوال كمعاملات

\n\n
    \n
  • المرونة: يمكنك كتابة دالة واحدة تقوم بأشياء مختلفة اعتماداً على الدالة التي تمررها إليها.
  • \n
  • قابلية القراءة: يصبح الكود تصريحياً — تصف ماذا تفعل، وليس كيف تفعله.
  • \n
  • إعادة الاستخدام: تتخلص من تكرار الكود عن طريق استخراج الأنماط الشائعة في دوال عليا.
  • \n
\n\n

الأساسيات: أنواع الدوال (Function Types)

\n\n

في Kotlin، الدوال هي كائنات من الدرجة الأولى. هذا يعني أن لها نوعها الخاص. يتم وصف نوع الدالة كالتالي: (المعاملات) -> نوعالإرجاع. على سبيل المثال:

\n\n
// دالة تأخذ Int وترجع String\nval intToString: (Int) -> String = { number -> "الرقم: $number" }\n\n// دالة لا تأخذ شيئاً ولا ترجع شيئاً\nval doNothing: () -> Unit = { println("مرحباً!") }\n\n// دالة بمعاملين\nval sum: (Int, Int) -> Int = { a, b -> a + b }\n
\n\n

لاحظ Unit — وهو مشابه لـ void في Java/JavaScript. إذا كانت الدالة لا ترجع شيئاً، فسيكون نوعها () -> Unit.

\n\n

كيف تمرر دالة كمعامل: المثال الأول

\n\n

لنفترض أننا نكتب دالة تقوم بعملية ما على رقم مرتين. بدلاً من تثبيت العملية بشكل ثابت، سنمررها كمعامل:

\n\n
fun applyTwice(x: Int, operation: (Int) -> Int): Int {\n    val firstResult = operation(x)\n    return operation(firstResult)\n}\n\n// الاستخدام:\nval result = applyTwice(5) { it * 2 } // تعبير لامدا\nprintln(result) // سيُطبع: 20 (5*2 = 10, 10*2 = 20)\n\n// أو باستخدام دالة مسماة:\nfun double(x: Int) = x * 2\nval result2 = applyTwice(5, ::double)\nprintln(result2) // أيضاً 20\n
\n\n

أترى كم أنيق؟ في الحالة الأولى استخدمنا تعبير لامدا (دالة مجهولة)، وفي الثانية استخدمنا مرجعاً لدالة موجودة عبر عامل التشغيل ::. كلا الطريقتين صحيحتان، وسنشرحهما بالتفصيل.

\n\n

طرق تمرير الدالة (شرح مفصل)

\n\n

1. تعبيرات لامدا (الطريقة الأكثر شيوعاً)

\n\n

لامدا هي دالة مجهولة يمكن تمريرها مباشرة. في Kotlin، لتعبيرات لامدا بناء جملة موجز:

\n\n
val list = listOf(1, 2, 3, 4, 5)\n\n// نمرر لامدا إلى دالة filter\nval evenNumbers = list.filter { it % 2 == 0 }\nprintln(evenNumbers) // [2, 4]\n\n// إذا كان هناك عدة معاملات:\nval numbersWithIndex = list.mapIndexed { index, value -> "$index: $value" }\nprintln(numbersWithIndex) // ["0: 1", "1: 2", ...]\n
\n\n

مهم: إذا كانت لامدا هي آخر معامل في الدالة، يمكن وضعها خارج الأقواس. هذا يجعل الكود يبدو كبنية لغة مدمجة. هكذا تعمل filter و map و forEach وغيرها.

\n\n

مثال مع تحديد المعامل بشكل صريح (عند وجود أكثر من معامل واحد):

\n\n
fun performAction(a: Int, b: Int, action: (Int, Int) -> String) {\n    println(action(a, b))\n}\n\n// الاستدعاء مع لامدا\nperformAction(3, 4) { x, y -> "المجموع: ${x + y}" }\n                

المدونات

توصيات الكتب