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) }) }