تكرار السؤال: …
الإجابة المختصرة
inline تدمج كود الدالة واللامدا في مكان الاستدعاء؛ noinline تمنع دمج لامدا معينة؛ crossinline تسمح بالدمج وتمنع non-local returns.
الشرح
تزيل inline عبء تخصيص كائنات للـ lambdas وتستبدل الاستدعاء بالكود المباشر. إذا كانت الدالة تستقبل أكثر من لامدا ونريد تمرير إحداها ككائن عادي نستخدم noinline. أما crossinline فتُستخدم عندما تُستدعى اللامدا داخل نطاق آخر (كـ Runnable أو Coroutine)، فتمنع اللامدا من تنفيذ return خارجي غير موضعي ينهي الدالة الأصلية.
مثال بالكود
val callbacks = mutableListOf<() -> Unit>()
inline fun performWork(
crossinline onAsyncCallback: () -> Unit,
noinline normalCallback: () -> Unit,
) {
// The lambda runs inside another object/context (a Runnable), so it must be crossinline:
// a non-local `return` from it would be illegal there.
val task = Runnable { onAsyncCallback() }
Thread(task).start()
// The lambda is stored as an object, which an inlined lambda cannot be → noinline
callbacks += normalCallback
}أخطاء شائعة
- جعل الدوال الضخمة inline مما يؤدي لتضخم حجم الـ bytecode (Code Bloat).
- محاولة استخدام inline على دوال عادية لا تستقبل معاملات من نوع Lambda دون تحقيق أي فائدة من التضمين.