الدوال في Kotlin: fun والمعاملات و Lambda
الدالة مجموعة أوامر لها اسم، تكتبها مرة وتستدعيها متى شئت. والدوال في Kotlin مرنة جداً: يمكن كتابتها في سطر واحد، ومعاملاتها يمكن أن تكون لها قيم افتراضية وأسماء، ويمكن تمريرها كقيم لدوال أخرى. هذه المرونة تجعل كود أندرويد الحديث، وخاصة واجهات Jetpack Compose، قصيراً وواضحاً.
تعريف دالة
Section titled “تعريف دالة”fun greet() { println("أهلاً بك في Kotlin!")}
fun add(a: Int, b: Int): Int { return a + b}
fun main() { greet() println(add(3, 4))}أهلاً بك في Kotlin!7fun: الكلمة التي تبدأ بها أي دالة.a: Int, b: Int: المعاملات، ولكل معامل نوعه إجبارياً.: Intبعد القوسين: نوع القيمة المرجعة.- الدالة التي لا تُرجع شيئاً مفيداً، مثل
greet، نوعهاUnit، ولا نكتبه عادة.
الدوال ذات التعبير الواحد
Section titled “الدوال ذات التعبير الواحد”إذا كانت الدالة تُرجع تعبيراً واحداً، اختصرها بعلامة =:
fun square(x: Int) = x * x
fun isEven(n: Int) = n % 2 == 0لاحظ أننا لم نكتب نوع القيمة المرجعة: Kotlin تستنتجه. square(5) تُرجع 25، و isEven(4) تُرجع true.
القيم الافتراضية
Section titled “القيم الافتراضية”يمكن أن تعطي المعامل قيمة تُستخدم إذا لم يرسل المستدعي قيمة:
fun makeTea(sugar: Int = 2): String = "شاي بـ $sugar ملاعق سكر"
println(makeTea())println(makeTea(0))شاي بـ 2 ملاعق سكرشاي بـ 0 ملاعق سكرالمعاملات المسماة
Section titled “المعاملات المسماة”عند الاستدعاء، تستطيع كتابة اسم كل معامل، فيصبح الكود مقروءاً مثل الجملة، ولا يهم الترتيب:
fun createUser(name: String, age: Int, city: String = "القاهرة"): String { return "$name ($age سنة) من $city"}
println(createUser("عمر", 15))println(createUser(age = 20, name = "منى", city = "جدة"))عمر (15 سنة) من القاهرةمنى (20 سنة) من جدةما فائدة ذلك؟ قارن: createUser("منى", 20, "جدة") مقابل createUser(name = "منى", age = 20, city = "جدة"). الثانية أوضح بكثير، خاصة عندما تكثر المعاملات أو تتشابه أنواعها. مثل الاستمارة التي مكتوب بجانب كل خانة اسمها.
الدوال المجهولة (Lambda)
Section titled “الدوال المجهولة (Lambda)”في Kotlin، الدالة قيمة تستطيع وضعها في متغير، أو تمريرها لدالة أخرى. والدالة بلا اسم تكتب بين قوسين معقوفين وتسمى Lambda:
val double = { x: Int -> x * 2 }println(double(21))42- قبل السهم
->المعاملات، وبعده الكود. - آخر سطر في الـ Lambda هو قيمتها المرجعة تلقائياً.
وأجمل استخدام لها مع القوائم:
val numbers = listOf(1, 2, 3)println(numbers.map { it * 10 })numbers.forEach { println("الرقم $it") }[10, 20, 30]الرقم 1الرقم 2الرقم 3لاحظ شيئين:
- عندما يكون للـ Lambda معامل واحد، لا داعي لتسميته؛ يُسمى تلقائياً
it. - عندما تكون الـ Lambda آخر معامل للدالة، تُكتب خارج القوسين:
map { ... }بدلاً منmap({ ... }).
هذا الأسلوب هو أساس Jetpack Compose في أندرويد، حيث تُبنى الواجهات بدوال تستقبل Lambda مثل: Button(onClick = { ... }) { Text("اضغط") }.
جرّب بنفسك
Section titled “جرّب بنفسك”اكتب دالة تحسب السعر بعد الخصم، مع نسبة افتراضية 10:
fun priceAfterDiscount(price: Double, percent: Double = 10.0) = price - price * percent / 100
fun main() { println(priceAfterDiscount(200.0)) println(priceAfterDiscount(200.0, percent = 25.0))}180.0150.0تحدٍّ: اكتب دالة grade(score: Int): String تستخدم when بدون قيمة لتُرجع «ممتاز» أو «ناجح» أو «راسب»، ثم استخدم map لتحويل قائمة درجات إلى قائمة تقديرات.
أخطاء شائعة
Section titled “أخطاء شائعة”- نسيان نوع المعامل:
fun add(a, b)خطأ. كل معامل يحتاج نوعه:a: Int. - نسيان return في الدالة ذات الأقواس المعقوفة: إذا أعلنت نوعاً مرجعاً مثل
: Int، يجب أن تُرجع قيمة بـreturn. - محاولة تغيير المعامل داخل الدالة: المعاملات في Kotlin تُعامل مثل
val، فلا يمكن إعادة إسنادها. انسخها في متغيرvarإن احتجت.
اختبر نفسك
Section titled “اختبر نفسك”سؤال
ما ناتج listOf(1, 2, 3).map { it + 1 }؟
map تطبق الـ Lambda على كل عنصر، و it هو العنصر الحالي، فتزيد كل قيمة واحداً.
سؤال
أي استدعاء صحيح للدالة fun order(item: String, qty: Int = 1)؟
مع المعاملات المسماة لا يهم الترتيب، لكن item ليس له قيمة افتراضية فلا يمكن حذفه.
الخلاصة
Section titled “الخلاصة”- الدالة تبدأ بـ
fun، ولكل معامل نوعه، ونوع القيمة المرجعة بعد القوسين. fun square(x: Int) = x * xاختصار للدالة ذات التعبير الواحد.- القيم الافتراضية والمعاملات المسماة تجعل الاستدعاء مرناً وواضحاً.
- Lambda دالة مجهولة بين
{ }، والمعامل الوحيد اسمهitتلقائياً. - الـ Lambda الأخيرة تُكتب خارج القوسين، وهذا أساس أسلوب Jetpack Compose.