0Pricing
Kotlin Academy · درس

معدّلا noinline وcrossinline

تحكّم في سلوك التضمين لمعاملات lambda محددة داخل دوال inline.

معدّلا noinline وcrossinline درس مجاني في Kotlin Academy على CoddyKit. هذا هو الدرس 2 من أصل 4. يمكنك قراءة الدرس كاملاً أدناه مجاناً — ثم تمرن عليه مباشرة في المتصفح باستخدام محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7. هذا الدرس جزء من مسار التعلم في Kotlin Academy، وتقدمك يتزامن عبر الويب وتطبيق CoddyKit. تتضمن دورة Kotlin Academy 4 دروس في المجموع.

المشكلة التي تحلها inline — والمشكلة التي تقدمها

عندما تكون الدالة inline، تُضمَّن كل معاملات لامبدا الخاصة بها افتراضيًا. وأحيانًا تحتاج إلى عدم تضمين لامبدا معينة — مثلًا لتخزينها أو تمريرها إلى دالة غير inline.

noinline: الإبقاء على لامبدا ككائن

ضع noinline قبل معامل لامبدا محدد لاستثنائه من التضمين، مع إبقاء بقية المعاملات مضمنة.

inline fun doWork(
    action: () -> Unit,
    noinline callback: () -> Unit   // stored, not inlined
) {
    action()                        // inlined at call site
    scheduleCallback(callback)      // passed as object — valid
}

متى يكون noinline ضروريًا

يجب استخدام noinline عندما تكون لامبدا:

  • مخزَّنة في متغير أو حقل
  • ممرَّرة إلى دالة تتوقع نوع دالة
  • مُعادة من الدالة inline

crossinline: منع عمليات الإرجاع غير المحلية

يُستخدم crossinline عندما تُستدعى لامبدا مضمنة في سياق تنفيذ مختلف (مثلًا داخل لامبدا أخرى أو في مؤشر ترابط مختلف). وهو يخبر المترجم: ضمّن لامبدا هذه، لكن لا تسمح بعمليات الإرجاع غير المحلية داخلها.

inline fun runAsync(crossinline block: () -> Unit) {
    Thread {
        block()   // block is inlined but cannot use non-local return
    }.start()
}

لماذا تكون عمليات الإرجاع غير المحلية خطرة هنا

إذا كان بإمكان block استخدام return غير محلي، فسيحاول الإرجاع من الدالة التي استدعت runAsync. ولكن عند تشغيل مؤشر الترابط، قد تكون تلك الدالة قد عادت بالفعل — مما يؤدي إلى سلوك غير معرّف. ويمنع crossinline حدوث ذلك أثناء الترجمة.

الجمع بين noinline وcrossinline

يمكن لدالة inline واحدة أن تجمع بين المعاملات العادية ومعاملات noinline وcrossinline:

inline fun orchestrate(
    crossinline setup: () -> Unit,
    action: () -> Unit,
    noinline teardown: () -> Unit
) {
    Thread { setup() }.start()
    action()
    register(teardown)
}

خطأ المترجم من دون crossinline

إذا مررت لامبدا مضمنة إلى سياق لامبدا من دون crossinline، فسيصدر المترجم: "Can't inline 'block' here: it may contain non-local returns. Add crossinline modifier."

الاستخدام في المكتبة القياسية

تستخدم المكتبة القياسية crossinline في دوال مثل Sequence { } وبعض منشئات coroutine، مما يضمن تشغيل لامبدا التي يقدّمها المستخدم بأمان في سياق مختلف.

noinline لا يعطّل inline

لا يؤدي وضع noinline على معامل واحد إلى إيقاف التضمين في الدالة بأكملها. يظل جسم الدالة وجميع معاملات لامبدا الأخرى مضمنة. أما لامبدا التي وُسمت بـ noinline وحدها فتحافظ على هويتها ككائن.

اعتبارات الأداء

يتسبب noinline في تكلفة تخصيص لامبدا المعتادة لذلك المعامل الواحد. أما crossinline فيظل يضمّن لامبدا — والقيد الوحيد هو منع عمليات الإرجاع غير المحلية. ولا يؤثر أي من المُعدِّلين في تضمين المعاملات الأخرى.

جدول الملخص

ملخص المُعدِّلات:

  • من دون مُعدِّل → تُضمَّن لامبدا بالكامل، وتُسمح عمليات الإرجاع غير المحلية
  • noinline → تبقى لامبدا ككائن، ويمكن تخزينها أو تمريرها
  • crossinline → تُضمَّن لامبدا، وتُمنع عمليات الإرجاع غير المحلية

تحقق سريع

متى يجب استخدام noinline مع معامل لامبدا في دالة inline؟

مراجعة: noinline وcrossinline

أهم النقاط:

  • noinline: يُبقي لامبدا واحدة ككائن داخل دالة مضمنة في بقية أجزائها
  • crossinline: يضمّن لامبدا لكنه يمنع عمليات الإرجاع غير المحلية، لاستخدامها بأمان عبر السياقات المختلفة
  • ينطبق كلا المُعدِّلين على كل معامل على حدة، وليس على الدالة بأكملها

الأسئلة الشائعة

هل درس «معدّلا noinline وcrossinline» مجاني؟

نعم — نص درس «معدّلا noinline وcrossinline» كامل متاح مجاناً هنا على الويب. لتمرينه بشكل تفاعلي (محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7) وفتح باقي دورة Kotlin Academy، انتقل إلى CoddyKit PRO. تتضمن دورة Kotlin Academy 4 دروس في المجموع.

ماذا ستتعلم في «معدّلا noinline وcrossinline»؟

تحكّم في سلوك التضمين لمعاملات lambda محددة داخل دوال inline. تتمرن على Kotlin Academy مع أكواد عملية تشغلها مباشرة في المتصفح، ومدرس ذكاء اصطناعي متاح 24/7 يجيب على أسئلتك أثناء عملك.

هل أحتاج إلى خبرة سابقة لأبدأ Kotlin Academy؟

لا تُشترط خبرة سابقة. Kotlin Academy على CoddyKit منظم للمبتدئين حتى المتقدمين، لذا يمكنك البدء من هنا أو من البداية والتقدم بسرعتك الخاصة. هذا هو الدرس 2 من أصل 4.

كم من الوقت يستغرق درس «معدّلا noinline وcrossinline»؟

معظم دروس CoddyKit تستغرق حوالي 5–10 دقائق. كل منها موجز وتفاعلي، لذا تحرز تقدماً مستمراً وتستأنف من حيث توقفت عبر الويب والتطبيق.

هل يمكنني كتابة وتشغيل أكواد في درس Kotlin Academy هذا؟

نعم. كل درس في Kotlin Academy يتضمن محرر أكواد مدمج، لذا تكتب وتشغل أكواداً حقيقية مباشرة في متصفحك وتحصل على تعليقات فورية من الذكاء الاصطناعي — بدون إعداد محلي.

جميع الدروس في هذه الدورة

  1. دوال inline: إزالة الحمل الزائد لـ Lambda
  2. معدّلا noinline وcrossinline
  3. معاملات النوع reified: الوصول إلى T وقت التشغيل
  4. أنماط reified العملية: التحليل وDI والتسلسل
← العودة إلى Kotlin Academy