var و val في Kotlin: ما الفرق؟ تحليل كامل
\n\nإذا كنت قد بدأت للتو رحلتك مع Kotlin أو أتيت من لغات أخرى (Java, Python, JavaScript)، فإن أحد الأسئلة الأولى التي ستطرحها هو: لماذا نحتاج إلى كلمتين رئيسيتين للإعلان عن المتغيرات؟ بالفعل، لماذا التعقيد إذا كان بإمكاننا الاكتفاء بكلمة واحدة؟ الإجابة تكمن في فلسفة اللغة: تم إنشاء Kotlin لجعل الكود أكثر أمانًا ووضوحًا وقابلية للتنبؤ. والفرق بين var و val ليس مجرد نزوة، بل أداة قوية لإدارة الحالة.
دعنا نفهم بالأمثلة متى نستخدم var ومتى نستخدم val، ولماذا هذا مهم لكودك.
ما هما var و val؟ تعريفات أساسية
\n\nلنبدأ بالأبسط.
\n\n- \n
var(من الإنجليزية variable) — متغير قابل للتغيير. يمكنك إعادة تعيين قيمة جديدة له عدة مرات كما تريد. \n val(من الإنجليزية value) — مرجع غير قابل للتغيير (للقراءة فقط). بعد التهيئة، لا يمكنك تغيير قيمته. وهو مشابه لـfinalفي Java أوconstفي JavaScript (مع بعض التحفظات). \n
إليك أبسط مثال:
\n\nfun main() {\n var x = 10\n x = 20 // OK: var يمكن تغييره\n\n val y = 30\n // y = 40 // خطأ في الترجمة: val لا يمكن إعادة تعيينه\n\n println("x = $x, y = $y")\n}\n\nيبدو كل شيء واضحًا، لكن الشيطان، كما هو الحال دائمًا، يكمن في التفاصيل.
\n\nالفرق الرئيسي: قابلية تغيير المرجع مقابل قابلية تغيير الكائن
\n\nهنا يحدث الالتباس غالبًا. val يضمن أن المرجع إلى الكائن لن يتغير، لكنه لا يضمن ثبات الكائن نفسه.
دعنا نوضح بمثال قائمة:
\n\nfun main() {\n val numbers = mutableListOf(1, 2, 3)\n // numbers = mutableListOf(4, 5, 6) // خطأ: val لا يمكن إعادة تعيينه\n\n numbers.add(4) // لكن هذا ممكن! نحن نغير محتوى الكائن\n numbers[0] = 100 // وهذا أيضًا ممكن\n\n println(numbers) // [100, 2, 3, 4]\n}\n\nلاحظ: لقد أعلنا numbers كـ val، لكننا نضيف ونغير العناصر بهدوء. لماذا؟ لأن val يحمي فقط المرجع نفسه (المتغير numbers)، وليس الكائن الذي يشير إليه.
إذا كنت تريد الثبات الكامل، يجب استخدام المجموعات غير القابلة للتغيير (listOf, mapOf, setOf) مع val في نفس الوقت.
fun main() {\n val immutableNumbers = listOf(1, 2, 3)\n // immutableNumbers.add(4) // خطأ: listOf يُرجع قائمة غير قابلة للتغيير\n // immutableNumbers[0] = 100 // خطأ\n}\n\nهذه نقطة مهمة يتم السؤال عنها غالبًا في المقابلات. تذكر: val ≠ كائن غير قابل للتغيير.
\n\nمتى نستخدم var ومتى نستخدم val؟
\n\nالقاعدة الذهبية في Kotlin: استخدم val أينما كان ذلك ممكنًا، و var فقط عندما يكون ضروريًا حقًا. لماذا؟
- \n
- الأمان. كلما قل عدد المتغيرات القابلة للتغيير، قل احتمال تغيير القيمة عن طريق الخطأ في مكان غير متوقع. هذا مهم بشكل خاص في البرمجة متعددة الخيوط. \n
- قابلية القراءة. عندما ترى
val، تعرف فورًا أن القيمة لن تتغير. هذا يبسط فهم الكود. \n - الأسلوب الوظيفي. تشجع Kotlin البرمجة الوظيفية، حيث يعتبر الثبات أحد المبادئ الأساسية. \n
إليك مثال حيث يكون var مبررًا:
fun main() {\n var counter = 0\n while (counter < 10) {\n println("Counter: $counter")\n counter++ // العداد يجب أن يتغير\n }\n}\n\nوهذا مثال حيث var هو ممارسة سيئة ويمكن استبداله