Kotlin和RxJava – 为什么我的Single.zip()不能编译?

我在这里有点疯狂 我试图创建一个Observable<BigDecimal>扩展函数(针对RxJava 2.x)来发射排放的平均值,但是我得到了Single.zip()函数的编译错误。 有没有人有什么想法我做错了? 我试图与所有我的类型明确,并没有工作…

 import io.reactivex.Observable import io.reactivex.Single import java.math.BigDecimal fun Observable<BigDecimal>.sum() = reduce { total, next -> total + next } //compile error fun Observable<BigDecimal>.average() = publish().autoConnect(2).let { Single.zip(it.sum().toSingle(), it.count()) { sum, count -> sum / BigDecimal.valueOf(count) } } 

在这里输入图像描述

类型推断大多不适用于rxJava2。 这实际上不是一个类型推断问题。 Kotlin通常会生成扩展方法,以用kotlin函数类型替换SAM,但由于某些原因,此技术对于重写的方法不起作用。

更多细节在这里https://youtrack.jetbrains.com/issue/KT-13609

作为选项,您可以尝试为lambda参数指定类型

 fun Observable<BigDecimal>.average() = publish().autoConnect(2).let { Single.zip(it.sum().toSingle(), it.count(), BiFunction { sum: BigDecimal, count: Long -> sum / BigDecimal.valueOf(count) }) } 

类型推理由于某种原因而失败,必须以某种方式在此上下文中推断出多种类型的组合。

您可以使用更传统的(不幸的是更详细的)语法显式指定类型,如下所示:

 fun Observable<BigDecimal>.average() = publish().autoConnect(2).let { Single.zip(it.sum().toSingle(), it.count(), BiFunction<BigDecimal, Long, BigDecimal> { sum, count -> sum / BigDecimal.valueOf(count) }) } 

更新:

我刚刚发现了一个类似的问题,这里的实际问题是,Kotlin无法推断出您尝试调用哪个Single.zip超载。 从官方文档 :

如果Java类具有多个采用功能接口的方法,则可以使用将lambda转换为特定SAM类型的适配器函数来选择需要调用的方法。 这些适配器功能也是由编译器在需要时生成的。

所以事实证明,使用更明确的SAM构造函数本身就解决了这个问题,并给出了类型推断(基本上,我以前的答案是使用比实际需要更长的语法):

 fun Observable<BigDecimal>.average(): Single<BigDecimal> = publish().autoConnect(2).let { Single.zip(it.sum().toSingle(), it.count(), BiFunction { sum, count -> sum / BigDecimal.valueOf(count) }) }