مقدمة: وداعًا switch-case؟ مرحبًا when!
إذا أتيت إلى Kotlin من عالم Java أو C# أو JavaScript، فإن أول ما تبحث عنه على الأرجح هو العامل المألوف switch-case. وهنا تنتظرك مفاجأة: في Kotlin لا يوجد switch-case كلاسيكي. بدلاً من ذلك، تقدم اللغة أداة أكثر قوة ومرونة — when.
على Stack Overflow، يجمع سؤال "How to implement switch-case statement in Kotlin" آلاف المشاهدات. هذا طبيعي: يعتاد المطورون على تركيبات معينة ويريدون إيجاد ما يماثلها. لكن الحقيقة هي أن when في Kotlin ليست مجرد بديل لـ switch. إنها تطوره، الذي يعمل تحت الغطاء بشكل أذكى وأسرع.
في هذه المقالة، لن نعرض فقط كيفية كتابة when. سننظر تحت الغطاء: سنعرف إلى ماذا يتم ترجمة الكود الخاص بك، ولماذا هو أسرع من switch في بعض السيناريوهات، وكيفية استخدام when بنسبة 100%.
1. بناء الجملة الأساسي: من switch-case إلى when
في البداية — أبسط مثال. لنفترض أن لدينا تركيب Java القديم الجيد:
// Javaint day = 3;String dayName;switch (day) { case 1: dayName = "الاثنين"; break; case 2: dayName = "الثلاثاء"; break; case 3: dayName = "الأربعاء"; break; default: dayName = "يوم غير معروف";}في Kotlin سيبدو هذا كالتالي:
// Kotlinval day = 3val dayName = when (day) { 1 -> "الاثنين" 2 -> "الثلاثاء" 3 -> "الأربعاء" else -> "يوم غير معروف"}هنا نرى بالفعل ميزتين رئيسيتين:
- لا يوجد break — يخرج Kotlin تلقائيًا من الكتلة بعد تنفيذ الفرع.
- إرجاع قيمة — يمكن تعيين النتيجة لمتغير.
2. كيف يعمل when تحت الغطاء: البايت كود والتحسين
الآن الجزء الأكثر إثارة للاهتمام. عندما تكتب when، يقوم مترجم Kotlin بتحليل شروطك واختيار الطريقة المثلى للتنفيذ. دعنا نلقي نظرة على البايت كود (تقريبًا، بدون تفاصيل زائدة).
الحالة 1: when مع الثوابت (مثل switch-case)
إذا كنت تستخدم when مع أعداد صحيحة أو سلاسل نصية أو ثوابت enum، يقوم المترجم بإنشاء جدول انتقال (tableswitch أو lookupswitch). هذه هي نفس الآلية التي يستخدمها Java لـ switch-case. الفرق هو أن Kotlin يفعل ذلك تلقائيًا، دون تدخل منك.
الحالة 2: when مع أي شروط
إذا كتبت شيئًا مثل:
when (x) { in 1..10 -> "صغير" in 11..100 -> "متوسط" else -> "كبير"}لا يمكن للمترجم استخدام جدول انتقال. يقوم بإنشاء سلسلة من if-else. لكن Kotlin يفعل ذلك بأقصى قدر من الكفاءة: يتم فحص الشروط بالترتيب، وبمجرد العثور على تطابق — يتوقف التنفيذ.
الحالة 3: when بدون وسيط
هذا سحر منفصل تمامًا. إذا كتبت:
when { x > 0 -> "موجب" x < 0 -> "سالب" else -> "صفر"}يحول المترجم هذا إلى if-else عادية. لكن بناء الجملة أنقى بكثير من if المتداخلة.
الخلاصة: Kotlin لا ينسخ switch-case فقط. إنه يختار بذكاء بين جدول الانتقال و if-else، لجعل الكود الخاص بك يعمل بأسرع ما يمكن.
3. الإمكانيات المتقدمة لـ when: ما لا يوجد في switch
when يمكنها فعل أكثر بكثير من مجرد مقارنة القيم. إليك بعض الميزات القاتلة:
3.1. التحقق من الأنواع (smart cast)
fun describe(obj: Any): String = when (obj) { is String -> "سلسلة نصية طولها ${obj.length}" // smart cast إلى String is Int -> "عدد صحيح" is List<*> -> "قائمة من ${obj.size} عناصر" else -> "نوع غير معروف"}