使用函数引用重写Kotlin中的Java代码发生SAM类型冲突
我有一个使用方法引用的示例Java代码,我想将其重写为Kotlin。Java版本正在使用方法参考,解决方案简洁明了。但另一方面,我不能在Kotlin中使用方法引用。我唯一能写的版本是下面的一个。似乎使用函数引用重写Kotlin中的Java代码发生SAM类型冲突,java,lambda,kotlin,rx-java2,method-reference,Java,Lambda,Kotlin,Rx Java2,Method Reference,我有一个使用方法引用的示例Java代码,我想将其重写为Kotlin。Java版本正在使用方法参考,解决方案简洁明了。但另一方面,我不能在Kotlin中使用方法引用。我唯一能写的版本是下面的一个。似乎Function3{s:String,b:Boolean,i:Int->combine(s,b,i)}可以以更简洁的方式编写(如果可能的话,方法引用将是完美的) 我是科特林的新手,如果有任何线索,我将不胜感激 Java import io.reactivex.Observable; public c
Function3{s:String,b:Boolean,i:Int->combine(s,b,i)}
可以以更简洁的方式编写(如果可能的话,方法引用将是完美的)
我是科特林的新手,如果有任何线索,我将不胜感激
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;
}
}
以下函数都不能用参数调用
提供:@CheckReturnValue@SchedulerSupport公共最终乐趣组合测试(p0:((观察员)->单位)!,p1:((观察员)->单位)!,p2:
((观察者)->单位)!,p3:((?,?,?,?)->?)!:
看得见!在io.reactivex.Observable中定义
@CheckReturnValue@SchedulerSupport public open fun CombineTest(p0:ObservableSource!、p1:ObservableSource!、p2:
ObservableSource!,p3:io.reactivex.functions.Function3!):
看得见!在io.reactivex.Observable中定义
@CheckReturnValue@SchedulerSupport public open fun CombineTest(p0:Function!,out
(??…??>!,p1:Int,vararg p2:observesSource!):
看得见!在io.reactivex.Observable中定义
编辑2
解决回答中提到的问题
import io.reactivex.rxkotlin.Observables
class TestKotlin {
fun test() {
Observables.combineLatest(strings(), booleans(), integers(), this::combine)
}
}
您也可以在Kotlin中使用,就像在Java中使用方法引用表达式一样。例如,Kotlin中的combine
函数引用为KFunction3
,如下所示:
val f: kotlin.reflect.KFunction3<String, Boolean, Int, Double> = this::combine
fun test() = TODO()
val exector:Executor = TODO()
exector.execute(::test)
//::test compile to java code as below:
Runnable task = new Runnable(){
public void run(){
test();
}
};
为什么方法引用表达式在Java中可以正常工作,但在Kotlin中使用失败
基于以上内容,您可以看到中有许多重载的combinelateest
方法。例如,以下两项无法使Kotlin正确使用:
combineLatest(
ObservableSource<out T1>,
ObservableSource<out T2>,
ObservableSource<out T3>,
Function3<T1, T2, T3, out R>
)
combineLatest(
ObservableSource<out T1>,
ObservableSource<out T2>,
ObservableSource<out T3>,
ObservableSource<out T4>,
Function4<T1, T2, T3, T4, out R>
)
因此,在使用lambda/之前必须使用自适应,例如:
val f:io.reactivex.functions.Function3<String,Boolean,Int,Double> =this::combine
// type mismatch error ---^
typealias RxFunction3<T1, T2, T3, R> = io.reactivex.functions.Function3<T1,T2,T3,R>
val f: RxFunction3<String, Boolean, Int, Double> = RxFunction3{ s, b, i-> 1.0}
typealias RxFunction3<T1, T2, T3, R> = io.reactivex.functions.Function3<T1,T2,T3,R>
fun <T1,T2,T3,R> KFunction3<T1,T2,T3,R>.toFunction3(): RxFunction3<T1, T2,T3,R> {
return RxFunction3 { t1, t2, t3 -> invoke(t1, t2, t3) }
}
Observable.combineLatest(
strings(),
booleans(),
integers(),
// v--- convert KFunction3 to RxFunction3 explicitly
this::combine.toFunction3()
)
@holi java的答案很好,它解释了为什么会出现这个问题,这里我为那些只想解决这个问题的人提供了一个快速解决方案: 在
rxJava2
中,使用io.reactivex.rxkotlin.Observables
而不是io.reactivex.Observable
组合您的观察值:
Observables.combineLatest(src1, src2, ::yourFunction)
这应该是开箱即用的。首先,我不是最令人沮丧的人。你试过了吗?“我不能在Kotlin中使用方法引用”为什么不?@holi java当然可以tried@AleksanderMielczarek您是否在Kotlin中尝试过:
CombineTest(strings()、booleans()、integers()、this::combine)
?@holi java请参见编辑的问题谢谢您的回答:)。直到今天,我还不知道存在这样的问题。刚刚找到解决这个问题的RxKotlin。@AleksanderMielczarek一点也不。我刚才在rx-java2中也发现了这个问题。我从未使用过,:)。使用导入io.reactivex.rxkotlin.observates
而不是常规的observates。类描述为“帮助Kotlin lambda支持的SAM适配器”
Observable.combineLatest(
strings(),
booleans(),
integers(),
// v--- convert KFunction3 to RxFunction3 explicitly
this::combine.toFunction3()
)
Observables.combineLatest(src1, src2, ::yourFunction)