Kotlin和RxJava2 zip运算符-使用提供的参数无法调用以下函数

K.O*_*.Os 6 kotlin android-studio rx-java rx-java2 android-studio-3.0

使用Android Studio 3.0 IDE在Kotlin中编写.zip Observable时遇到问题。

这是我的代码:

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()
}
Run Code Online (Sandbox Code Playgroud)

但是,我的IDE(Android Studio 3.0 RC2)在.zip运算符下划线并说:

使用提供的参数不能调用以下任何函数。zip((((observer:Observer!>)?Unit)!,((observer:Observer!>)?Unit)!,(((observer:Observer)?Unit))!,(((t1:List,t2:List,t3 :布尔)?布尔)!)其中T1 =列表,T2 =列表,T3 =布尔,R =布尔值的zip(source1:(((observer:Observer)?Unit)!, source2:((observer:Observer)? unit)!, source3:((观察者:Observer)?Unit)!,拉链:((t1:T1,t2:T2,t3:T3)?R)!):可观察!定义于io.reactivex.Observable zip((((observer:Observer!>)?Unit)!,((observer:Observer!>)?Unit))!,(((t1:List,t2:List)?Boolean)!,布尔值),其中T1 =列表,T2 =列表,R =布尔值用于zip(source1:(((observer:Observer)?Unit)!, source2:((observer:Observer)?Unit)!, zipper:((t1: T1,t2:T2)?R)!, delayError:布尔):可观察!在io.reactivex.Observable zip(ObservableSource!> !, ObservableSource!> !, ObservableSource !, io.reactivex.functions.Function3 !, in List !, Boolean!out Boolean!>!)中定义,其中T1 =列表, T2 =列表,T3 =布尔值,R =用于布尔值的布尔值zip(源1:ObservableSource !,源2:ObservableSource !,源3:ObservableSource !,拉链:Function3!):可观察!在io.reactivex.Observable zip(ObservableSource!> !, ObservableSource!> !, BiFunction !, in List !, out Boolean!> !, Boolean)中定义,其中T1 =列表,T2 =列表,R =有趣zip的布尔值( source1:ObservableSource!,source2:ObservableSource !,拉链:BiFunction!,delayError:布尔值):Observable!在io.reactivex.Observable中定义 in Boolean !, out Boolean!>!)其中T1 =列表,T2 =列表,T3 =布尔值,R =布尔值的乐趣zip(source1:ObservableSource !, source2:ObservableSource !, source3:ObservableSource !,拉链:Function3!) :可观察!在io.reactivex.Observable zip(ObservableSource!> !, ObservableSource!> !, BiFunction !, in List !, out Boolean!> !, Boolean)中定义,其中T1 =列表,T2 =列表,R =有趣zip的布尔值( source1:ObservableSource!,source2:ObservableSource !,拉链:BiFunction!,delayError:布尔值):Observable!在io.reactivex.Observable中定义 in Boolean !, out Boolean!>!)其中T1 =列表,T2 =列表,T3 =布尔值,R =布尔值的乐趣zip(source1:ObservableSource !, source2:ObservableSource !, source3:ObservableSource !,拉链:Function3!) :可观察!在io.reactivex.Observable zip(ObservableSource!> !, ObservableSource!> !, BiFunction !, in List !, out Boolean!> !, Boolean)中定义,其中T1 =列表,T2 =列表,R =有趣zip的布尔值( source1:ObservableSource!,source2:ObservableSource !,拉链:BiFunction!,delayError:布尔值):Observable!在io.reactivex.Observable中定义 ObservableSource!> !, BiFunction !, in List !,布尔值!> !,布尔值),其中T1 =列表,T2 =列表,R =布尔值的zip(source1:ObservableSource !, source2:ObservableSource !,拉链:BiFunction! ,delayError:布尔):可观察!在io.reactivex.Observable中定义 ObservableSource!> !, BiFunction !, in List !,布尔值!> !,布尔值),其中T1 =列表,T2 =列表,R =布尔值的zip(source1:ObservableSource !, source2:ObservableSource !,拉链:BiFunction! ,delayError:布尔):可观察!在io.reactivex.Observable中定义

如何使其与Kotlin一起使用?

Joe*_*ski 5

由于某种原因,使用RxJava 1.1.7时,它考虑将zipper参数的类型显式指定为Func3,这是一个冗余SAM构造函数(它是),并允许您将其替换为lambda。但是,使用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()
}
Run Code Online (Sandbox Code Playgroud)

注意:我设法在不显式指定type参数的情况下使其工作Function3。是否可以推断类型取决于它所使用的Kotlin或RxJava版本。如果没有,您总是可以更加明确:

Function3<List<String>, List<Int>, Boolean, Boolean> { ... }
Run Code Online (Sandbox Code Playgroud)

编辑:还有一个更简单的方法:io.reactivex.rxkotlin.Observables改用。这是一个内联函数,为我们在幕后进行丑陋的类型声明。然后,您可以执行以下操作:

import io.reactivex.rxkotlin.Observables
...

Observables.zip(updateStringEventsSubject.buffer(trigger),
                updateIntEventsSubject.buffer(trigger),
                trigger, 
                ::saveEvents)
Run Code Online (Sandbox Code Playgroud)