Kotlin const vs val: ما الفرق وماذا تختار؟

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

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

ابدأ الدورة

Kotlin const vs val: ما الفرق وماذا تختار؟

\n\n

أنت تكتب كودًا بلغة Kotlin وفجأة تتساءل: "ما الفرق بين const و val؟ كلاهما يبدو غير قابل للتغيير، أليس كذلك؟". سؤال ممتاز! هذه النقطة تربك حتى المطورين ذوي الخبرة الذين ينتقلون من Java أو لغات أخرى. ليس من المستغرب أن موضوع "What is the difference between 'const' and 'val'?" على Stack Overflow يحصل على آلاف المشاهدات. اليوم سنحسم هذا الأمر نهائيًا، وننظم النظرية ونعززها بأمثلة كود حية.

\n\n

هل أنت مستعد؟ هيا بنا!

\n\n

نبذة مختصرة: ما هو val؟

\n\n

لنبدأ بالأسهل. val (من كلمة value - قيمة) هو مرجع غير قابل للتغيير. يمكنك تعيين قيمة له مرة واحدة فقط ولا يمكنك تغييرها أبدًا. يبدو مألوفًا؟ نعم، إنه مشابه لـ final في Java أو readonly في C#.

\n\n
val name: String = "أليس"\nname = "بوب" // خطأ في الترجمة! لا يمكن إعادة تعيين Val
\n\n

لكن هناك فارق مهم: val يضمن أن المرجع لن يتغير، لكنه لا يضمن ثبات الكائن نفسه. إذا استخدمت val مع قائمة قابلة للتغيير (MutableList)، فلا يزال بإمكانك إضافة وحذف العناصر.

\n\n
val numbers = mutableListOf(1, 2, 3)\nnumbers.add(4) // يعمل!\n// numbers = mutableListOf(5, 6) // خطأ! لا يمكن إعادة تعيين المرجع
\n\n

يمكن تهيئة val إما أثناء التصريح أو لاحقًا في الكود (على سبيل المثال، في المُنشئ أو كتلة init). يتم حساب قيمته أثناء تنفيذ البرنامج (runtime).

\n\n

وماذا عن const؟ الحارس الصارم لوقت الترجمة

\n\n

const هو الأخ الأكثر صرامة لـ val. إنه أيضًا غير قابل للتغيير، لكن بقدرة خارقة: يجب أن تكون القيمة معروفة في مرحلة الترجمة (compile-time). بعبارة أخرى، إنه ثابت حقيقي يمكن للمترجم إدراجه مباشرة في الكود، مثل الثابت المضمن.

\n\n

لدى const قواعد صارمة:

\n
    \n
  • يمكن التصريح به فقط على مستوى الملف (خارج الفئة) أو داخل object / companion object.
  • \n
  • يجب أن يكون من نوع بدائي أو نوع String.
  • \n
  • لا يمكن أن يكون نتيجة استدعاء دالة أو عملية حسابية - فقط قيمة حرفية أو ثابت آخر.
  • \n
\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\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n
المعيارconst valval
وقت التهيئةفي مرحلة الترجمةفي مرحلة التنفيذ
أين يمكن التصريحالمستوى الأعلى، object، companion objectفي أي مكان (داخل الفئة، الدالة، المُنشئ)
أنواع البياناتفقط الأنواع البدائية و Stringأي أنواع (بما في ذلك الكائنات، القوائم)
الأداءأقصى (تضمين)قياسي
الاستخدام في التعليقات التوضيحيةنعملا
\n\n

مثال عملي: التعليقات التوضيحية والأداء

\n\n

أحد الاستخدامات

المدونات

توصيات الكتب