ここでちょっとおかしくなりそうだ。放出の平均を放出する_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はSAMをkotlinの機能型に置き換える拡張メソッドを生成しますが、このテクニックは何らかの理由でオーバーライドされたメソッドでは機能しません。
詳細はこちら https://youtrack.jetbrains.com/issue/KT-13609
オプションとして、ラムダ引数の型を指定しようとすることができます
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クラスに機能的なインターフェースを取る複数のメソッドがある場合、ラムダを特定の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)
})
}