我有一个示例Java代码使用方法引用,我想重写为Kotlin . Java版本使用方法参考,解决方案简短明了 . 但另一方面,我不能在Kotlin中使用方法参考 . 我设法编写的唯一版本如下所示 . 似乎 Function3 { s: String, b: Boolean, i: Int -> combine(s, b, i) }
可以用更干净的方式编写(如果可能的方法参考将是完美的) .
我是Kotlin的新手,所以我会感激任何线索 .
Java
import io.reactivex.Observable;
public class TestJava {
Observable<String> strings() {
return Observable.just("test");
}
Observable<Boolean> booleans() {
return Observable.just(true);
}
Observable<Integer> integers() {
return Observable.just(1);
}
void test() {
Observable.combineLatest(strings(), booleans(), integers(),
this::combine);
}
double combine(String s, boolean b, int i) {
return 1.0;
}
}
Kotlin
import io.reactivex.Observable
import io.reactivex.functions.Function3
class TestKotlin {
fun strings(): Observable<String> {
return Observable.just("test")
}
fun booleans(): Observable<Boolean> {
return Observable.just(true)
}
fun integers(): Observable<Int> {
return Observable.just(1)
}
fun test() {
Observable.combineLatest(strings(), booleans(), integers(),
Function3 { s: String, b: Boolean, i: Int -> combine(s, b, i) })
}
fun combine(s: String, b: Boolean, i: Int): Double {
return 1.0
}
}
EDIT
以下Kotlin中的方法引用给出了错误 .
fun test() {
Observable.combineLatest(strings(), booleans(), integers(), this::combine)
}
fun test() {
Observable.combineLatest(strings(), booleans(), integers(), TestKotlin::combine)
}
使用提供的参数不能调用以下任何函数:@CheckReturnValue @SchedulerSupport public final fun combineLatest(p0:((Observer) - > Unit)!,p1:((Observer) - > Unit)!,p2 :( (Observer) - > Unit)!,p3:((???,???,???) - > ???)!):Observable <(??? ??? ???)>!在io.reactivex.Observable中定义@CheckReturnValue @SchedulerSupport public open fun combineLatest(p0:ObservableSource!,p1:ObservableSource!,p2:ObservableSource!,p3:io.reactivex.functions.Function3!):Observable <(??? . ???)>!在io.reactivex.Observable中定义@CheckReturnValue @SchedulerSupport public open fun combineLatest(p0:Function!,out(??? .. ???)>!,p1:Int,vararg p2:ObservableSource!):Observable <(? ?? .. ???)>!在io.reactivex.Observable中定义
EDIT 2
RxKotlin解决了答案中提到的问题 .
import io.reactivex.rxkotlin.Observables
class TestKotlin {
fun test() {
Observables.combineLatest(strings(), booleans(), integers(), this::combine)
}
}
2 回答
您也可以在Kotlin中使用Function Reference Expression,就像Java中的方法引用表达式一样 . 例如,
combine
函数引用为Kotlin中的KFunction3
,如下所示:在java中,方法引用表达式可以分配给任何 compatible Functional Interface,但是您不能将Function Reference Expression分配给任何函数类型,即使它们是 compatible ,例如:
实际上,Kotlin使用SAM Conversions将lambda / Function Reference Expression转换为Java Functional Interface的实现,这意味着Kotlin执行如下操作:
Why 方法参考表达式可以在Java中正常工作,但在Kotlin中使用Function Reference Expression失败了吗?
基于上面的内容,您可以看到rx-java2中有许多重载的
combineLatest
方法 . 例如,以下两个不能使Kotlin正确使用Function Reference Expression:正如我所说,Kotlin使用SAM Conversions将lambda / Function Reference Expression转换为Java Functional Interface,但它无法直接分配给Java Functional Interface .
Kotlin中
combineLatest
方法的第4个参数,编译器根本无法推断其类型,因为第4个参数类型可以是io.reactivex.functions.Function3
或ObservableSource
. 因为ObservableSource
也是一个Java Functional Interface .遇到像这样的SAM Conversion冲突时,可以使用将lambda转换为特定SAM类型的 adapter function ,例如:
因此,在使用lambda / Function Reference Expression之前必须使用自适应,例如:
Then 您可以使用如下的Function Reference Expression,例如:
@ holi-java答案很棒,它解释了为什么会出现这个问题,在这里我为那些只想摆脱问题的人提供快速解决方案:
在
rxJava2
中使用io.reactivex.rxkotlin.Observables
而不是io.reactivex.Observable
来组合您的observable:Observables.combineLatest(src1, src2, ::yourFunction)
这应该是开箱即用的 .