التأمل والاستبطان في Kotlin: كيف تنظر داخل الكود الخاص بك
\n\nتخيل أنك مبرمج يكتب كودًا يحلل نفسه بنفسه. يبدو وكأنه خيال علمي؟ في عالم Kotlin، هذا واقع. التأمل والاستبطان هما الأدوات التي تحول الكود الخاص بك من منفذ بسيط إلى مبرمج فوقي حقيقي. إذا كنت ترغب يومًا في الحصول على معلومات عن الفئات بشكل ديناميكي، أو استدعاء دوال بأسمائها، أو العمل مع التعليقات التوضيحية في وقت التشغيل، فهذه المقالة لك.
\n\nسنشرح كيف يستخدم Kotlin، كونه لغة تعمل فوق JVM، التأمل، وكيف يمكنك من خلال أمثلة بسيطة إضافة السحر إلى مشاريعك. هيا بنا!
\n\nما هو التأمل والاستبطان؟ الفرق الذي يجب معرفته
\n\nقبل الغوص في الكود، دعنا نوضح المصطلحات. غالبًا ما يتم الخلط بين هذه المفاهيم، لكن هناك خط رفيع بينها.
\n\n- \n
- الاستبطان — هو قدرة البرنامج على "النظر إلى نفسه". يمكنك الحصول على معلومات حول بنية الفئات: خصائصها، دوالها، منشئاتها. الأمر أشبه بفتح غطاء محرك السيارة والنظر إلى ما بداخله. \n
- التأمل — هو شيء أكثر قوة. لا تنظر فقط، بل تغير سلوك البرنامج أثناء التنفيذ. يمكنك استدعاء دوال لم تكن تعرفها في مرحلة التجميع، وإنشاء كائنات بناءً على اسم الفئة كنص. \n
في Kotlin، يرتبط التأمل ارتباطًا وثيقًا بتأمل JVM، لكن له واجهات برمجة تطبيقات خاصة بـ Kotlin (مثل KClass، KFunction). ونعم، للعمل مع التأمل ستحتاج إلى إضافة تبعية في ملف build.gradle.kts:
dependencies {\n implementation("org.jetbrains.kotlin:kotlin-reflect:1.9.22")\n}\n\n\nبدونها، ستتمكن فقط من استخدام الإمكانيات الأساسية، مثل javaClass. لكن لتجربة Kotlin كاملة، قم بتثبيت المكتبة.
KClass: أداتك الرئيسية للاستبطان
\n\nفي Java، اعتدنا على Class<?>. في Kotlin، نظيره هو KClass. إنها نقطة الدخول إلى عالم التأمل. يمكن الحصول على KClass بطريقتين:
// الطريقة 1: عبر كائن الفئة\nval myClass: KClass<String> = String::class\n\n// الطريقة 2: عبر مثيل\nval str = "مرحبًا، أيها العالم!"\nval classFromInstance: KClass<out String> = str::class\n\n\nالآن لديك access إلى الكثير من المعلومات: اسم الفئة، الحزمة، المنشئات، الخصائص، الدوال. لنلق نظرة على مثال:
\n\ndata class User(val name: String, val age: Int)\n\nfun main() {\n val kClass = User::class\n println("اسم الفئة: ${kClass.simpleName}") // User\n println("الحزمة: ${kClass.qualifiedName}") // com.example.User\n println("عدد الخصائص: ${kClass.memberProperties.size}") // 2 (name, age)\n \n kClass.memberProperties.forEach { prop ->\n println("خاصية: ${prop.name}, النوع: ${prop.returnType}")\n }\n}\n\n\nهذا هو الاستبطان الخالص في Kotlin — نحن فقط ننظر إلى البنية. لا تغيير في السلوك.
\n\nالحصول على معلومات حول الدوال والمنشئات
\n\nأحيانًا تحتاج إلى معرفة الدوال الموجودة في الفئة، أو حتى استدعائها. لهذا نستخدم KFunction.
class Calculator {\n fun add(a: Int, b: Int): Int = a + b\n fun multiply(a: Int, b: Int): Int = a * b\n}\n\nfun main() {\n val calcClass = Calculator::class\n println("دوال الفئة Calculator:")\n calcClass.memberFunctions.forEach { func ->\n println(" - ${func.name} (المعلمات: ${func.parameters})")\n }\n}\n\n\nسيكون الناتج تقريبًا كالتالي:
\nدوال الفئة Calculator:\n - add (المعلمات: [a, b])\n - multiply (المعلمات: [a, b])\n\n\nالتأمل في العمل: استدعاء الدوال وإنشاء الكائنات
\n\nوالآن الجزء الممتع — التأمل. لنفترض أن لديك نصًا باسم دالة،