properties - Kotlin-تهيئة الممتلكات باستخدام "بواسطة كسول" مقابل "متأخر"




(6)

إذا كنت تستخدم الحاوية Spring وترغب في تهيئة حقل الحبة غير lateinit ، فإن lateinit مناسبة بشكل أفضل.

    @Autowired
    lateinit var myBean: MyBean

في Kotlin إذا كنت لا ترغب في تهيئة خاصية فئة داخل المنشئ أو في الجزء العلوي من نص الفصل ، فلديك أساسًا هذان الخياران (من مرجع اللغة):

  1. تهيئة كسول

lazy () هي وظيفة تأخذ lambda وتُرجع مثيل Lazy الذي يمكن أن يكون مفوضًا لتنفيذ خاصية lazy: أول استدعاء للحصول على () ينفذ lambda الذي تم تمريره إلى lazy () ويتذكر النتيجة ، المكالمات اللاحقة للحصول على () ببساطة إرجاع النتيجة التي تم تذكرها.

مثال

public class Hello {

   val myLazyString: String by lazy { "Hello" }

}

لذا فإن المكالمة الأولى والمكالمات الفرعية ، أينما كانت ، إلى myLazyString ستعود إلى "Hello"

  1. التهيئة المتأخرة

عادةً ، يجب تهيئة الخصائص المعلنة على أنها نوع غير فارغ في المُنشئ. ومع ذلك ، في كثير من الأحيان إلى حد ما هذه ليست مريحة. على سبيل المثال ، يمكن تهيئة الخصائص من خلال حقن التبعية ، أو في طريقة الإعداد لاختبار وحدة. في هذه الحالة ، لا يمكنك توفير مُهيئ غير خالٍ في المُنشئ ، لكنك لا تزال ترغب في تجنب عمليات التحقق الخالية عند الرجوع إلى الخاصية داخل نص الفصل الدراسي.

لمعالجة هذه الحالة ، يمكنك وضع علامة على الخاصية باستخدام معدِّل متأخر:

public class MyTest {

   lateinit var subject: TestSubject

   @SetUp fun setup() { subject = TestSubject() }

   @Test fun test() { subject.method() }
}

لا يمكن استخدام المعدّل إلا في خصائص var التي تم الإعلان عنها داخل نص فئة (وليس في المُنشئ الأساسي) ، وفقط عندما لا يكون للخاصية منشأ أو أداة تعيين مخصصة. يجب أن يكون نوع الخاصية غير فارغ ، ويجب ألا يكون نوعًا بدائيًا.

لذا ، كيف تختار بشكل صحيح بين هذين الخيارين ، لأن كلاهما يمكن أن يحل نفس المشكلة؟


إذا كنت تستخدم متغيرًا غير قابل للتغيير ، فمن الأفضل التهيئة باستخدام by lazy { ... } أو val . في هذه الحالة ، يمكنك التأكد من أنه سيتم دائمًا التهيئة عند الحاجة وعند 1 مرة على الأكثر.

إذا كنت تريد متغيرًا غير صفري ، يمكنه تغيير قيمته ، استخدم lateinit var . في تطوير Android ، يمكنك تهيئته لاحقًا في مثل هذه الأحداث مثل onCreate و onResume . كن على علم ، أنه إذا اتصلت بطلب REST UninitializedPropertyAccessException: lateinit property yourVariable has not been initialized إلى هذا المتغير ، فقد يؤدي ذلك إلى استثناء UninitializedPropertyAccessException: lateinit property yourVariable has not been initialized ، لأن الطلب يمكن تنفيذه بشكل أسرع من أن المتغير يمكن تهيئته.


بالإضافة إلى إجابة hotkey الجيدة ، إليك كيف أختار بين الاثنين في الممارسة:

lateinit هي lateinit الخارجية: عندما تحتاج إلى أشياء خارجية لتهيئة قيمتها عن طريق استدعاء طريقة.

على سبيل المثال عن طريق الاتصال:

private lateinit var value: MyClass

fun init(externalProperties: Any) {
   value = somethingThatDependsOn(externalProperties)
}

بينما يكون lazy عندما يستخدم فقط التبعيات الداخلية لكائنك.


بالإضافة إلى كل الإجابات الرائعة ، هناك مفهوم يسمى التحميل البطيء:

التحميل الكسول هو نمط تصميم شائع الاستخدام في برمجة الكمبيوتر لتأجيل تهيئة كائن حتى النقطة التي يحتاج إليها.

باستخدامه بشكل صحيح ، يمكنك تقليل وقت تحميل التطبيق الخاص بك. وطريقة Kotlin في تنفيذها هي من خلال lazy() الذي يقوم بتحميل القيمة المطلوبة إلى المتغير كلما دعت الحاجة.

ولكن يتم استخدام lateinit عندما تكون متأكدًا من أن المتغير لن يكون فارغًا أو فارغًا وسيتم تهيئته قبل استخدامه - على طريقة onResume() لنظام Android - وبالتالي لا تريد إعلانه كنوع لاغٍ.


المتأخرة مقابل كسول

  1. lateinit

    1) استخدمه مع متغير قابل للتغيير

    lateinit var name: String       //Allowed
    lateinit val name: String       //Not Allowed

    ii) مسموح به مع أنواع البيانات غير القابلة للإلغاء فقط

    lateinit var name: String       //Allowed
    lateinit var name: String?      //Not Allowed

    ج) إنه يعد للمترجم أن القيمة ستتم تهيئتها في المستقبل.

ملاحظة : إذا حاولت الوصول إلى المتغير المتأخر دون تهيئة ، فإنه يلقي UnInitializedPropertyAccessException.

  1. كسول

    i) تم تصميم تهيئة كسول لمنع التهيئة غير الضرورية للكائنات.

    ii) لن تتم تهيئة المتغير الخاص بك إلا إذا كنت تستخدمه.

    ج) تتم تهيئة مرة واحدة فقط. في المرة القادمة عند استخدامها ، تحصل على القيمة من ذاكرة التخزين المؤقت.

    4) إنه آمن للخيط (يتم تهيئته في الخيط حيث يتم استخدامه لأول مرة. تستخدم سلاسل العمليات الأخرى نفس القيمة المخزنة في ذاكرة التخزين المؤقت).

    5) يمكن أن يكون المتغير var أو val .

    سادسا) المتغير يمكن أن يكون لاغيا أو لاغيا .


يعود الفضل إلى Amit Shekhar

lateinit

lateinit هو التهيئة المتأخرة.

عادةً ، يجب تهيئة الخصائص المعلنة على أنها نوع غير فارغ في المُنشئ. ومع ذلك ، في كثير من الأحيان إلى حد ما هذه ليست مريحة. على سبيل المثال ، يمكن تهيئة الخصائص من خلال حقن التبعية ، أو في طريقة الإعداد لاختبار وحدة. في هذه الحالة ، لا يمكنك توفير مُهيئ غير خالٍ في المُنشئ ، لكنك لا تزال ترغب في تجنب عمليات التحقق الخالية عند الرجوع إلى الخاصية داخل نص الفصل الدراسي.

مثال:

public class Test {

  lateinit var mock: Mock

  @SetUp fun setup() {
     mock = Mock()
  }

  @Test fun test() {
     mock.do()
  }
}

كسول

كسول هو التهيئة البطيئة.

lazy() هي وظيفة تأخذ lambda وتقوم بإرجاع مثيل lazy الذي يمكن أن يكون بمثابة مفوض لتنفيذ خاصية lazy: أول استدعاء get() ينفذ lambda الذي تم تمريره إلى lazy() ويتذكر النتيجة ، المكالمات اللاحقة get() ببساطة إرجاع النتيجة التي تم تذكرها.

مثال:

public class Example{
  val name: String by lazy { Amit Shekhar }
}




kotlin