Kotlin const vs val: ما الفرق وماذا تختار؟
\n\nأنت تكتب كودًا بلغة Kotlin وفجأة تتساءل: "ما الفرق بين const و val؟ كلاهما يبدو غير قابل للتغيير، أليس كذلك؟". سؤال ممتاز! هذه النقطة تربك حتى المطورين ذوي الخبرة الذين ينتقلون من Java أو لغات أخرى. ليس من المستغرب أن موضوع "What is the difference between 'const' and 'val'?" على Stack Overflow يحصل على آلاف المشاهدات. اليوم سنحسم هذا الأمر نهائيًا، وننظم النظرية ونعززها بأمثلة كود حية.
هل أنت مستعد؟ هيا بنا!
\n\nنبذة مختصرة: ما هو val؟
\n\nلنبدأ بالأسهل. val (من كلمة value - قيمة) هو مرجع غير قابل للتغيير. يمكنك تعيين قيمة له مرة واحدة فقط ولا يمكنك تغييرها أبدًا. يبدو مألوفًا؟ نعم، إنه مشابه لـ final في Java أو readonly في C#.
val name: String = "أليس"\nname = "بوب" // خطأ في الترجمة! لا يمكن إعادة تعيين Val\n\nلكن هناك فارق مهم: val يضمن أن المرجع لن يتغير، لكنه لا يضمن ثبات الكائن نفسه. إذا استخدمت val مع قائمة قابلة للتغيير (MutableList)، فلا يزال بإمكانك إضافة وحذف العناصر.
val numbers = mutableListOf(1, 2, 3)\nnumbers.add(4) // يعمل!\n// numbers = mutableListOf(5, 6) // خطأ! لا يمكن إعادة تعيين المرجع\n\nيمكن تهيئة val إما أثناء التصريح أو لاحقًا في الكود (على سبيل المثال، في المُنشئ أو كتلة init). يتم حساب قيمته أثناء تنفيذ البرنامج (runtime).
وماذا عن const؟ الحارس الصارم لوقت الترجمة
\n\nconst هو الأخ الأكثر صرامة لـ val. إنه أيضًا غير قابل للتغيير، لكن بقدرة خارقة: يجب أن تكون القيمة معروفة في مرحلة الترجمة (compile-time). بعبارة أخرى، إنه ثابت حقيقي يمكن للمترجم إدراجه مباشرة في الكود، مثل الثابت المضمن.
لدى const قواعد صارمة:
- \n
- يمكن التصريح به فقط على مستوى الملف (خارج الفئة) أو داخل
object/companion object. \n - يجب أن يكون من نوع بدائي أو نوع
String. \n - لا يمكن أن يكون نتيجة استدعاء دالة أو عملية حسابية - فقط قيمة حرفية أو ثابت آخر. \n
// صحيح\nconst val PI = 3.14159\nconst val APP_NAME = "MyApp"\n\n// غير صحيح\nconst val currentTime = System.currentTimeMillis() // خطأ! القيمة غير معروفة في مرحلة الترجمة\nconst val userName = getName() // خطأ! استدعاء الدالة غير مسموح\n\nالاختلافات الرئيسية: const vs val في جدول
\n\nلتوضيح الأمر، إليك جدول مقارنة:
\n\n| المعيار | \nconst val | \nval | \n
|---|---|---|
| وقت التهيئة | \nفي مرحلة الترجمة | \nفي مرحلة التنفيذ | \n
| أين يمكن التصريح | \nالمستوى الأعلى، object، companion object | \nفي أي مكان (داخل الفئة، الدالة، المُنشئ) | \n
| أنواع البيانات | \nفقط الأنواع البدائية و String | \nأي أنواع (بما في ذلك الكائنات، القوائم) | \n
| الأداء | \nأقصى (تضمين) | \nقياسي | \n
| الاستخدام في التعليقات التوضيحية | \nنعم | \nلا | \n
مثال عملي: التعليقات التوضيحية والأداء
\n\nأحد الاستخدامات