Kotlin передает функцию в качестве параметра против реализации lambda

#kotlin #kotlin-extension #rx-kotlin

#kotlin #kotlin-расширение #rx-kotlin

Вопрос:

Я использую io.reactivex.rxkotlin функцию расширения:

 fun <T : Any> Observable<T>.subscribeBy(
        onError: (Throwable) -> Unit = onErrorStub,
        onComplete: () -> Unit = onCompleteStub,
        onNext: (T) -> Unit = onNextStub
        ): Disposable
  

И когда я использую это расширение, есть разница, выбираю ли я отправлять параметр или использую lambda.
Например

первая реализация:

 myObservable.subscribeBy { str ->
    // onNext
}
  

Вторая реализация:

 myObservable.subscribeBy({ throwable ->
    // onError
})
  
  • в первой реализации функция является onNext
  • и во второй реализации функция является onError

И я не уверен, почему.

Ответ №1:

Из функций более высокого порядка и лямбд:

В Kotlin существует соглашение, согласно которому, если последний параметр функции принимает функцию, лямбда-выражение, которое передается в качестве соответствующего аргумента, может быть помещено за скобки:

Итак, в вашем случае у вас есть функция, которая принимает три необязательных параметра. В первой реализации:

 myObservable.subscribeBy { str -> }
  

Вы используете эту функцию, чтобы опустить круглые скобки для последнего лямбда-параметра (который является onNext ). Однако, когда вы используете вторую реализацию:

 myObservable.subscribeBy({ throwable -> })
  

Поскольку она заключена в круглые скобки, это должен быть первый параметр, если только вы не должны были явно назвать его в качестве последнего параметра, например:

 myObservable.subscribeBy(onNext = { str -> })
  

Комментарии:

1. Я использовал subscribeBy раньше, но я не понял, в чем преимущество (ы) этой функции расширения по сравнению с subscribe самой по себе?!

Ответ №2:

subscribeBy Метод имеет преимущество именованных параметров, что позволило бы решить все проблемы.

Вы можете заметить, что использование лямбда-нотации устанавливает последний неназванный параметр, в то время как установка параметра напрямую устанавливает первый неназванный параметр.

Если вы назовете один из параметров, вы больше не сможете использовать лямбда-нотацию.