Оператор zip Kotlin и RxJava2-ни одна из следующих функций не может быть вызвана с предоставленными аргументами


У меня есть проблема с написанием.наблюдаемые молнии в Котлин, используя Android Studio интегрированная среда разработки 3.0.

Вот мой код:

internal var updateStringEventsSubject = PublishSubject.create<String>()
internal var updateIntEventsSubject = PublishSubject.create<Int>()

internal var triggerSave = PublishSubject.create<Boolean>()
internal var triggerStopAndSave = PublishSubject.create<Boolean>()

internal var normalSaveTrigger = triggerSave.debounce(30, TimeUnit.SECONDS)
internal var trigger = Observable.merge(normalSaveTrigger, triggerStopAndSave)

private fun saveEvents(
        strings: List<String>,
        integers: List<Int>,
        someBoolean: Boolean): Boolean {

    return true //doesn't matter for now
}

fun temp() {
    Observable.zip<List<String>, List<Int>, Boolean, Boolean>(updateStringEventsSubject.buffer(trigger),
            updateIntEventsSubject.buffer(trigger),
            trigger, { strings: List<String>, integers: List<Int>, someBoolean: Boolean -> saveEvents(strings, integers, someBoolean) })
            .subscribe()
}

Однако моя IDE (Android Studio 3.0 RC2) подчеркивает .оператор zip и говорит:

Ни одна из следующих функций не может быть вызвана с предоставленными аргументами. зип ((наблюдатель: наблюдатель!> ) → Единица измерения)!, ((наблюдатель: наблюдатель!> ) → Единица измерения)!, ((наблюдатель: наблюдатель) → единица измерения)!, ((Т1: список, Т2: список, Т3: булево) → булево)!) где T1 = список, T2 = Список, Т3 = логическое значение, Р = boolean для удовольствия зип(файлы source1: ((наблюдателя: наблюдатель) → блок)!, source2: ((наблюдатель: наблюдатель) → единица измерения)!, source3: ((наблюдатель: наблюдатель) → единица измерения)! застежки-молнии: ((Т1: Т1, Т2: Т2, Т3: Т3) → Р)!): Наблюдаемо! определено в io.реактивекс.Заметный зип ((наблюдатель: наблюдатель!> ) → Единица измерения)!, ((наблюдатель: наблюдатель!> ) → Единица измерения)!, ((Т1: список, Т2: список) → булево)!, Логическое) где T1 = список, Т2 = список, Р = boolean для удовольствия зип(файлы source1: ((наблюдателя: наблюдатель) → блок)!, source2: ((наблюдатель: Наблюдатель) → Единица)!, молния: ((t1: T1, t2: T2) → R)!, delayError: Boolean): наблюдаемо! определено в io.реактивекс.Заметный zip (ObservableSource!>!, ObservableSource!>!, ObservableSource!, Ио.реактивекс.функции.Функция 3!, в списке! в логическом смысле! из логических!>!) где T1 = список, Т2 = список, Т3 = логическое значение, Р = boolean для удовольствия зип(файлы source1: ObservableSource!, source2: ObservableSource!, source3: ObservableSource!, молния: функция 3!): Наблюдаемо! определено в io.реактивекс.Заметный zip (ObservableSource!>!, ObservableSource!>!- Бифункция!, в списке! из логических!>!, Логическое) где T1 = список, Т2 = список, Р = boolean для удовольствия зип(файлы source1: ObservableSource!, source2: ObservableSource!, молния: Бифункция!, delayError: Boolean): наблюдаемо! определено в io.реактивекс.Наблюдаемый

Как заставить его работать с Котлином?

2 3

2 ответа:

По какой-то причине, используя RxJava 1.1.7, он считает явное указание типа аргумента zipper как Func3 избыточным Sam-конструктором (которым он и является) и позволяет заменить его лямбдой. Однако при использовании RxJava 2.1.5 тип изменяется на Function3, и он больше не распознает его как интерфейс с одним абстрактным методом (которым он все еще является). Я не знаю, почему это так.

Независимо от этого, указание типа функции молнии сделает трюк:

import io.reactivex.functions.Function3
...

fun temp() {
    Observable.zip<List<String>, List<Int>, Boolean, Boolean>(updateStringEventsSubject.buffer(trigger),
            updateIntEventsSubject.buffer(trigger),
            trigger, Function3 { strings, integers, someBoolean -> saveEvents(strings, integers, someBoolean) } )
            .subscribe()
}

Примечание: I удалось заставить его работать без явного указания аргументов типа для Function3. Это может зависеть от того, какую версию Kotlin или RxJava вы используете, чтобы определить типы. Если нет, вы всегда можете быть более ясными:

Function3<List<String>, List<Int>, Boolean, Boolean> { ... }

Edit: Есть еще более простой способ: вместо этого используйте io.reactivex.rxkotlin.Observables. Это встроенная функция, которая делает уродливое объявление типа под капотом для нас. Тогда вы можете просто сделать это:

import io.reactivex.rxkotlin.Observables
...

Observables.zip(updateStringEventsSubject.buffer(trigger),
                updateIntEventsSubject.buffer(trigger),
                trigger, 
                ::saveEvents)

Благодаря @Joeleski я нашел ошибку. В моем случае я задал тип явно каждому параметру оператора zip, а затем обнаружил, что одна переменная имеет неправильный тип.