قائمة Kotlin لا تحتوي على add؟ نبحث عن الطرق المفقودة

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

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

ابدأ الدورة

لماذا "أخذ" منا Kotlin add و remove و put؟ نفهم الأمر مرة واحدة وإلى الأبد

\n\n

إذا كنت قد كتبت بلغة Java من قبل، ثم انتقلت إلى Kotlin، فمن المحتمل أنك واجهت هذه اللحظة من الحيرة الطفيفة. تقوم بإنشاء List، وتريد إضافة عنصر إليه - تكتب .add()، وتقوم بيئة التطوير بتسليط الضوء عليه باللون الأحمر. أو تحاول وضع قيمة في Map باستخدام .put() - وتتلقى خطأ مرة أخرى.

\n\n

هل هذا مألوف؟ بالتأكيد! السؤال "Kotlin's List missing "add", "remove", Map missing "put", etc?" على Stack Overflow حصد آلاف المشاهدات وعشرات التعليقات. إنها حجر عثرة حقيقي للمبتدئين، وحتى المطورين ذوي الخبرة يجدون أحيانًا أنفسهم يفكرون: "أين طرقاتي المعتادة؟"

\n\n

في هذه المقالة، لن نجيب على هذا السؤال فحسب. بل سنوضح كيف تحول فلسفة Kotlin هذا "النقص" إلى ميزتك الرئيسية. ستتعلم أفضل الممارسات للعمل مع المجموعات في عام 2025، وستتعلم اختيار النوع الصحيح من المجموعة، وستتوقف عن الخلط بين listOf و mutableListOf. هيا بنا!

\n\n

ما الجوهر؟ الثبات كأسلوب حياة

\n\n

أول شيء يجب فهمه: تم تصميم Kotlin منذ البداية كلغة تشجع على الكود الآمن والقابل للتنبؤ. أحد المبادئ الرئيسية هو الثبات (immutability) بشكل افتراضي.

\n\n

في Java، لديك واجهة واحدة List، وهي تحتوي دائمًا على طرق add() و remove() و set() وهكذا. حتى إذا قمت بإنشاء قائمة باستخدام List.of() (Java 9+)، فلا يزال لديك إمكانية الوصول إلى هذه الطرق - فهي تطرح استثناءً فقط أثناء التنفيذ. هذا غير مريح وغير آمن.

\n\n

اتبع Kotlin مسارًا مختلفًا. قام بتقسيم المجموعات إلى نوعين:

\n\n
    \n
  • غير قابلة للتغيير (للقراءة فقط): List، Set، Map - لا تحتوي على طرق تغير المحتوى.
  • \n
  • قابلة للتغيير (mutable): MutableList، MutableSet، MutableMap - هذه هي التي تحتوي على جميع الطرق المألوفة add و remove و put.
  • \n
\n\n

لهذا السبب بالتحديد، listOf(1, 2, 3) لا تحتوي على طريقة .add(). إنها تُرجع قائمة غير قابلة للتغيير. بينما mutableListOf(1, 2, 3) - تُرجع قائمة قابلة للتغيير، وتحتوي على .add().

\n\n

يبدو هذا منطقيًا؟ دعنا نلقي نظرة على الكود.

\n\n

أمثلة: ما يعمل وما لا يعمل

\n\n

إليك موقف كلاسيكي يربك المبتدئين:

\n\n
// ❌ خطأ! List لا تحتوي على add()\nval fruits = listOf("apple", "banana")\nfruits.add("orange") // خطأ في الترجمة\n\n// ✅ صحيح: استخدم MutableList\nval mutableFruits = mutableListOf("apple", "banana")\nmutableFruits.add("orange") // الآن يعمل!\nprintln(mutableFruits) // [apple, banana, orange]\n
\n\n

نفس القصة مع Map:

\n\n
// ❌ خطأ! Map لا تحتوي على put()\nval capitals = mapOf("Russia" to "Moscow", "France" to "Paris")\ncapitals.put("Germany", "Berlin") // خطأ في الترجمة\n\n// ✅ صحيح: استخدم MutableMap\nval mutableCapitals = mutableMapOf("Russia" to "Moscow", "France" to "Paris")\nmutableCapitals.put("Germany", "Berlin")\n// أو بشكل أقصر:\nmutableCapitals["Germany"] = "Berlin"\nprintln(mutableCapitals) // {Russia=Moscow, France=Paris, Germany=Berlin}\n
\n\n

لاحظ: بالنسبة لـ MutableMap، يمكنك استخدام الأقواس التشغيلية [] - وهذا هو put() تحت الغطاء. مريح جدًا!

\n\n

ولكن لماذا؟ لماذا يعقد Kotlin الحياة بهذا الشكل؟

\n\n

للوهلة الأولى، يبدو أن هذا صداع إضافي غير ضروري. لماذا يجب حفظ نوعين من المجموعات؟ في الواقع، هذا حل عبقري. إليك ثلاثة أسباب رئيسية:

\n\n

1. الأمان على مستوى الأنواع

\n

يقوم المترجم الآن بمراقبة عدم قيامك بتغيير قائمة عن طريق الخطأ والتي من المفترض أن تبقى

المدونات

توصيات الكتب