явный тип возврата при использовании rxjava2, завершаемого в лямбда-выражении - PullRequest
0 голосов
/ 25 сентября 2018
Android Studio 3.3
RxJava 2

У меня проблемы с пониманием явного возврата лямбды.

Например, я использую чистую архитектуру, и на моем уровне данных у меня есть следующий интерфейс и реализация (которые не возвращают никакойзавершено)

Интерфейс:

interface ISendMail {
    fun sendMail(tellNumber: String,
                 membershipNumber: String,
                 attachmentsType: String,
                 message: String,
                 subject: String)
}

Реализация:

class SendEmailImp : ISendMail {
    override fun sendMail(tellNumber: String, membershipNumber: String, attachmentsType: String, message: String, subject: String) {
        TODO("implement sending the email")
    }
}

На моем доменном уровне, и именно здесь у меня возникает проблема: Интерфейс возвращает завершаемый:

interface SendMail {
    fun sendEmail(tellNumber: String,
                  membershipNumber: String,
                  attachmentsType: String,
                  message: String,
                  subject: String): Completable
}

Реализация и проблема в том, что call () хочет вернуть Completable, но iSendMail.sendMail возвращает Unit:

class SendMailImp(val iSendMail: ISendMail) : SendMail {
    override fun sendEmail(tellNumber: String, membershipNumber: String, attachmentsType: String, message: String, subject: String): Completable {
        return Completable.fromCallable(object: Callable<Completable> {
            override fun call(): Completable {
                return iSendMail.sendMail(tellNumber, membershipNumber, attachmentsType, message, subject)
            }
        })
    }
}

Однако, если я использую лямбду, как этовсе работает нормально:

 return Completable.fromCallable {
            iSendMail.sendMail(tellNumber, membershipNumber, attachmentsType, message, subject)
        }  

Просто интересно, в чем разница между двумя разными методами, первый из которых является явным и ожидает возврата Completable.А второй, который использует лямбду?

Заранее большое спасибо,

1 Ответ

0 голосов
/ 25 сентября 2018
return Completable.fromCallable {
         iSendMail.sendMail(tellNumber, membershipNumber, attachmentsType, message, subject)
    }

сгенерирует следующий код Java

Completable.fromCallable((Callable)(new Callable() {
        // $FF: synthetic method
        // $FF: bridge method
        public Object call() {
           this.call();
           return Unit.INSTANCE;
        }

        public final void call() {
           SendMailImp.this.getISendMail().sendMail(tellNumber, membershipNumber, attachmentsType, message, subject);
        }
     }));

Так что, как видите, метод call() вернет экземпляр Unit.Итак, теперь, чтобы исправить проблему с вашим первым подходом, вам нужно явно определить тип вызываемого - Callable<Unit>

return Completable.fromCallable(object: Callable<Unit> {
            override fun call() {
                iSendMail.sendMail(tellNumber, membershipNumber, attachmentsType, message, subject)
            }
        })

Теперь компилятор понимает, что вызываемый должен возвращать Unit, поэтому он позволяет вызывать iSendMail.sendMail() безнужно явно вернуть Unit из функции call().

...