شرح تعابير لامدا

شرح تعابير لامدا


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


تعابير لامدا و RxJava


ما هي تعابير لامدا؟ تعد تعبيرات Lambda "مجرد" طريقة جديدة للقيام بنفس الشيء الذي يمكننا القيام به دائمًا ، ولكن بطريقة جديدة أكثر نظافة وأقل تفصيلاً لاستخدام الطبقات الداخلية المجهولة.


فئة داخلية مجهولة في Java هي فئة غير مسماة ، يجب استخدامها إذا كنت بحاجة إلى تجاوز أساليب الطبقة أو الواجهة. يمكن إنشاء فئة داخلية مجهولة من فئة أو واجهة.


على سبيل المثال:


abstract class Animal { abstract void speak(); } Animal a = new Animal() { void speak() { System.out.println("Woff"); } }; 

في Android ، نستخدم عادةً فئة داخلية مجهولة كمستمع ، على سبيل المثال ، للأزرار من هذا النوع:


 Button btn = findViewById(R.id.button); btn.setOnClickListener( new View.OnClickListener() { @Override public void onClick(final View view) { // Do some fancy stuff with the view parameter. } } ); 

دعنا نعود إلى تعابير لامدا. هذا هو الجزء التالي ، وهو جزء من الرمز السابق ، والذي يعتبر فئة داخلية مجهولة.


 new View.OnClickListener() { @Override public void onClick(final View view) { // Do some fancy stuff with the view parameter. } } 

يمكن استخدام تعبيرات Lambda فقط إذا كنت بحاجة إلى تجاوز طريقة واحدة على الأكثر. لحسن الحظ بالنسبة لنا ، تحتوي View.OnClickListener على واحدة فقط. ألق نظرة على الرمز أدناه. أي جزء تعتقد أنه علينا إزالته؟


 new View.OnClickListener() { @Override public void onClick(final View view) { // Do some fancy stuff with the view parameter. } } 

بعد إزالة جميع التعليمات البرمجية تقريبًا ، نحتاج إلى إضافة -> ، كما في الرمز أدناه. يمكن استخدام عرض معلمة الإدخال داخل الوظيفة بنفس الطريقة السابقة.


 (view) -> { // Do some fancy stuff with the view parameter. } 

في بعض الحالات ، قد تحتاج إلى إضافة نوع إلى معلمة ، إذا لم يتمكن المترجم من تخمينه ، يمكنك القيام بذلك عن طريق إضافته قبل المعلمة:


 (View view) -> { // Do some fancy stuff with the view parameter. } 

يمكنك أيضًا استخدام رمز متعدد الأسطر:


 (view) -> { Intent intent = new Intent(context, AuthActivity.class); intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK); view.getContext().startActivity(intent); } 

إذا كان لديك واجهة مع طريقة تأخذ معلمتين ...


 interface MyInterface { abstract void onMethod(int a, int b); } 

... سيبدو تعبير لامدا كما يلي:


 (a, b) -> { // Do some fancy stuff with the a and b parameter. } 

إذا كان للطريقة نوع إرجاع ...


 interface MySecondInterface { abstract int onSecondMethod(int a, int b); } 

... سيبدو تعبير لامدا كما يلي:


 (a, b) -> { return a + b; } 

ولكن هذا ليس كل شيء ، فهناك بعض الحالات الخاصة التي تجعل الشفرة أصغر. إذا كان نص الطريقة يحتوي على سطر واحد فقط من التعليمات البرمجية ، فيمكنك إزالة الأقواس المتعرجة {} . إذا قمت بإزالة الأقواس المتعرجة ، فستحتاج أيضًا إلى إزالة الفاصلة المنقوطة ، مع ترك ما يلي:


 (a, b) -> return a + b 

هناك شيء آخر يمكننا القيام به. إذا كان لدينا سطر واحد فقط من التعليمات البرمجية ، فيمكن للمترجم أن يفهم ما إذا كان الجزء الذي تم إرجاعه مطلوبًا أم لا ، لذا يمكننا تركه على النحو التالي:


 (a, b) -> a + b 

إذا كان لدينا رمز متعدد الأسطر ، فسوف ينزل إلى ما يلي:


 (a, b) -> { a+=1; return a + b; } 

إذن ماذا فعلنا؟ أخذنا هذا:


 new MySecondInterface() { @Override public int onSecondMethod(final int a, final int b) { return a + b; } }; 

وحولته إلى هذا:


 (a, b) -> a + b 

لم يبق سوى شيء واحد ، مراجع الطريقة. لنفترض أن لدينا واجهة ، كما كان من قبل ، وطريقة تقبل هذه الواجهة كمعلمة:


 public interface Callback { public void onEvent(int event); } public void myMethod(Callback callback){ } 

بدون تعبير لامدا ، ستبدو كما يلي:


 myMethod(new Callback() { @Override public void onEvent(final int state) { System.out.println(state); } }); 

بإضافة تعبير لامدا ، كما فعلنا من قبل ، نحصل على ما يلي:


 myMethod(state -> System.out.println(state)); 

لكن هذا ليس كل شيء إذا كان الكود المستخدم عبارة عن سطر واحد وكانت الوظيفة المطلوبة تأخذ معلمة واحدة ، فيمكننا تمرير مرجع الطريقة في هذا النموذج:


 myMethod(System.out::println); 

سيتم تمرير المعلمة تلقائيًا ، دون الحاجة إلى رمز آخر! حق مدهش؟ أتمنى أن تكون قد تعلمت شيئًا جديدًا!

Source: https://habr.com/ru/post/ar419395/


All Articles