我在这里有点疯狂.我正在尝试创建一个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)
}
}
Run Code Online (Sandbox Code Playgroud)
Ste*_*ngo 37
类型推断通常不适用于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)
})
}
Run Code Online (Sandbox Code Playgroud)
类型推断由于某种原因失败,必须以某种方式在此上下文中推断出多种类型的组合.
您可以使用更传统(并且遗憾的是更详细)的语法显式指定类型,如下所示:
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)
})
}
Run Code Online (Sandbox Code Playgroud)
更新:
我刚刚发现了一个类似的问题,这里的实际问题是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)
})
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
13652 次 |
| 最近记录: |