Rewrite Java code in Kotlin using the Reference function, SAM type conflict occurs

I have an example of Java code using a method reference that I want to rewrite in Kotlin. The Java version uses a reference to the method, the solution is short and clear. But, on the other hand, I can’t use the method link in Kotlin. The only version I managed to write is one of the following. It looks like it Function3 { s: String, b: Boolean, i: Int -> combine(s, b, i) }could be written in a cleaner way (if possible, the method reference would be perfect).

I am new to Kotlin, so I will be grateful for any tips.

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

The following links to methods in Kotlin give an error.

fun test() {
    Observable.combineLatest(strings(), booleans(), integers(), this::combine)
}

fun test() {
    Observable.combineLatest(strings(), booleans(), integers(), TestKotlin::combine)
}

: @CheckReturnValue @SchedulerSupport combLatest (p0: ((Observer) → Unit)!, p1: ((Observer) → Unit)!, p2: ((Observer) → Unit)!, p3: ((???,???,???) → ???)!): < (???..???) > ! io.reactivex.Observable @CheckReturnValue @SchedulerSupport public open fun combLatest (p0: ObservableSource!, p1: ObservableSource!, p2: ObservableSource!, p3: io.reactivex.functions.Function3!): < (???..???) > ! io.reactivex.Observable @CheckReturnValue @SchedulerSupport open fun combLatest (p0: !, out (???..???) > !, p1: Int, vararg p2: ObservableSource!): < (???..???) > ! io.reactivex.Observable

2

RxKotlin , .

import io.reactivex.rxkotlin.Observables

class TestKotlin {

    fun test() {
        Observables.combineLatest(strings(), booleans(), integers(), this::combine)
    }

}
+4
2

Reference Kotlin, Reference Reference Java. , combine KFunction3 Kotlin, :

val f: kotlin.reflect.KFunction3<String, Boolean, Int, Double> = this::combine

java Reference , a Reference Expression , , :

val f:io.reactivex.functions.Function3<String,Boolean,Int,Double> =this::combine
//                                                type mismatch error     ---^

, SAM Conversions lambda/ Reference Expression Java , , Kotlin - :

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, Reference Expression Kotlin

, , rx-java2. , Kotlin Function Reference Expression:

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>
)

, Kotlin SAM Conversions lambda/ Java , Java .

4- combineLatest , , 4- io.reactivex.functions.Function3 ObservableSource. ObservableSource Java .

SAM Conversion, , , SAM, :

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}

, lambda/ Reference, :

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) }
}

Reference, , :

Observable.combineLatest(
        strings(),
        booleans(), 
        integers(), 
        //             v--- convert KFunction3 to RxFunction3 explicitly
        this::combine.toFunction3()
)
+6

@holi-java , , , , :

rxJava2 io.reactivex.rxkotlin.Observables io.reactivex.Observable :

Observables.combineLatest(src1, src2, ::yourFunction)

.

+4

Source: https://habr.com/ru/post/1681522/


All Articles