Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/389.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用函数引用重写Kotlin中的Java代码发生SAM类型冲突_Java_Lambda_Kotlin_Rx Java2_Method Reference - Fatal编程技术网

使用函数引用重写Kotlin中的Java代码发生SAM类型冲突

使用函数引用重写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

我有一个使用方法引用的示例Java代码,我想将其重写为Kotlin。Java版本正在使用方法参考,解决方案简洁明了。但另一方面,我不能在Kotlin中使用方法引用。我唯一能写的版本是下面的一个。似乎
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)