【问题标题】:Observable.combineLatest cause error after updating to RxJava 2.x.x. - cannot infer typeObservable.combineLatest 更新到 RxJava 2.x.x 后导致错误。 - 无法推断类型
【发布时间】:2017-07-14 23:11:04
【问题描述】:

最近几天我试图将我的项目从 RxJava 1.x.x 迁移到 RxJava 2.x.x。我有这个简单的方法。如果我使用 rxjava 1.x.x (rx.Observable) 中的 Observable,一切都很好。但是,当我用“新”可观察对象(io.reactivex.Observable)替换它时,我收到一条错误消息:“类型推断失败。请明确指定”

fun <T1, T2, T3, R> combineLatestValue3Nullable(observable1: Observable<T1?>, observable2: Observable<T2?>, observable3: Observable<T3?>, merge: (T1, T2, T3?) -> R): Observable<R?> {
    return Observable.combineLatest(observable1, observable2, observable3) {
        value1, value2, value3 ->
        var result: R? = null
        if (value1 != null && value2 != null) {
            result = merge(value1, value2, value3)
        }
        result
    }
}

你知道我做错了什么吗?你能解释一下在 RxJava 2 中究竟是什么导致了这个错误吗?

有人 (here) 遇到了与此非常相似的问题。然而,他们在他们的解决方案中使用了 BiFuntion,它接受两个参数并创建一个结果。如您所见,我使用了更多参数 (3),因此我不能在这里使用 Bifunction。

【问题讨论】:

  • 不,我不会说这是一个重复的问题。我看到了他们的解决方案,但对我不起作用。他们正在使用 BiFuntion,它接受两个参数并创建一个结果。如您所见,我使用了更多参数 (3),因此我不能在这里使用 Bifunction。
  • 你说得对,这确实是一个不同的问题。如果只是更多参数,我认为您可以像使用 BiFunction 示例一样使用 Function3,但是您也有泛型来使事情复杂化。我认为这只有在您写出完整的 object 语法以创建具有显式类型的 Function3 时才有效。
  • 你不能在 RxJava 2 中使用空值(和可空类型)。这个函数永远不能被调用,因为可空类型的 Observable 不存在。如果您绝对必须识别缺少值,请使用 Optional。
  • @PepaHruška 有趣。我回答刚才的问题。请参阅my answer。如果您有任何疑问,请在我的答案下方添加评论。

标签: android kotlin rx-java rx-java2


【解决方案1】:

最后,我根据上面给出的建议找到了解决方案。首先应该提到的是我们根本不应该返回可为空的 Observable。如果我们需要检查传递给 combineLatest 的值,我们应该先检查它,而不是在 combineLatest 中检查它。

当我们移除可空性时,方法如下所示:

fun <T1, T2, T3, R> combineLatest(observable1: Observable<T1>, observable2: Observable<T2>, observable3: Observable<T3>, merge: (T1, T2, T3) -> R): Observable<R> {
    return Observable.combineLatest(observable1, observable2, observable3, Function3 {
        value1, value2, value3 ->
        merge(value1, value2, value3)
    })
}

我必须改变的唯一额外的事情是用 Function3 替换 lambda - 它解决了类型推断的问题。

如果 combineLatest 只有两个值,则可以使用 BiFuntion 而不是 Function3。

如果您需要传递例如 6 个变量来 combineLatest,您可以使用 Function6 等。

查看以下所有变体:

fun <T1, T2, R> combineLatest(observable1: Observable<T1>, observable2: Observable<T2>, merge: (T1, T2) -> R): Observable<R> {
    return Observable.combineLatest(observable1, observable2, BiFunction {
        value1, value2 ->
        merge(value1, value2)
    })
}

fun <T1, T2, T3, R> combineLatest(observable1: Observable<T1>, observable2: Observable<T2>, observable3: Observable<T3>, merge: (T1, T2, T3) -> R): Observable<R> {
    return Observable.combineLatest(observable1, observable2, observable3, Function3 {
        value1, value2, value3 ->
        merge(value1, value2, value3)
    })
}

fun <T1, T2, T3, T4, R> combineLatest(observable1: Observable<T1>, observable2: Observable<T2>, observable3: Observable<T3>, observable4: Observable<T4>, merge: (T1, T2, T3, T4) -> R): Observable<R> {
    return Observable.combineLatest(observable1, observable2, observable3, observable4, Function4 {
        value1, value2, value3, value4 ->
        merge(value1, value2, value3, value4)
    })
}

fun <T1, T2, T3, T4, T5, R> combineLatest(observable1: Observable<T1>, observable2: Observable<T2>, observable3: Observable<T3>, observable4: Observable<T4>, observable5: Observable<T5>, merge: (T1, T2, T3, T4, T5) -> R): Observable<R> {

    return Observable.combineLatest(observable1, observable2, observable3, observable4, observable5, Function5 {
        value1, value2, value3, value4, value5 ->
        merge(value1, value2, value3, value4, value5)
    })
}

fun <T1, T2, T3, T4, T5, T6, R> combineLatest(observable1: Observable<T1>, observable2: Observable<T2>, observable3: Observable<T3>, observable4: Observable<T4>, observable5: Observable<T5>, observable6: Observable<T6>, merge: (T1, T2, T3, T4, T5, T6) -> R): Observable<R> {
    return Observable.combineLatest(observable1, observable2, observable3, observable4, observable5, observable6, Function6 {
        value1, value2, value3, value4, value5, value6 ->
        merge(value1, value2, value3, value4, value5, value6)
    })
}

fun <T1, T2, T3, T4, T5, T6, T7, R> combineLatest(observable1: Observable<T1>, observable2: Observable<T2>, observable3: Observable<T3>, observable4: Observable<T4>, observable5: Observable<T5>, observable6: Observable<T6>, observable7: Observable<T7>, merge: (T1, T2, T3, T4, T5, T6, T7) -> R): Observable<R> {
    return Observable.combineLatest(observable1, observable2, observable3, observable4, observable5, observable6, observable7, Function7 {
        value1, value2, value3, value4, value5, value6, value7 ->
        merge(value1, value2, value3, value4, value5, value6, value7)
    })
}

fun <T1, T2, T3, T4, T5, T6, T7, T8, R> combineLatest(observable1: Observable<T1>, observable2: Observable<T2>, observable3: Observable<T3>, observable4: Observable<T4>, observable5: Observable<T5>, observable6: Observable<T6>, observable7: Observable<T7>, observable8: Observable<T8>, merge: (T1, T2, T3, T4, T5, T6, T7, T8) -> R): Observable<R> {
    return Observable.combineLatest(observable1, observable2, observable3, observable4, observable5, observable6, observable7, observable8, Function8 {
        value1, value2, value3, value4, value5, value6, value7, value8 ->
        merge(value1, value2, value3, value4, value5, value6, value7, value8)
    })
}

【讨论】:

    【解决方案2】:

    你在使用RxKotlin吗?如果没有,我建议尝试一下,因为它具有各种方法的 SAM 助手,包括combineLatest,这是受影响的方法之一。请参阅他们的docs 了解更多信息。

    【讨论】:

    • 是的,我正在使用 RxKotlin。
    【解决方案3】:

    我遇到了同样的问题。然后看到Kotlin有一个同名的函数,默认使用。所以我只是明确地导入了 RxJava 函数,这帮助我摆脱了错误:

    import io.reactivex.functions.Function3
    

    【讨论】:

      猜你喜欢
      • 2017-08-01
      • 2018-06-16
      • 2015-04-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-08-14
      • 1970-01-01
      相关资源
      最近更新 更多