您还可以像在Java中使用方法引用表达式一样,在Kotlin中使用函数引用表达式。例如,Kotlin中的
combine函数引用
KFunction3如下:
val f: kotlin.reflect.KFunction3<String, Boolean, Int, Double> = this::combine
在Java中,“方法引用表达式”可以分配给任何 兼容的* Functional
Interface,但是即使它们
兼容 ,也不能将“
函数引用表达式”分配给任何Function类型,例如: *
val f:io.reactivex.functions.Function3<String,Boolean,Int,Double> =this::combine// type mismatch error ---^
的确,Kotlin使用SAM转换将lambda /
函数引用表达式转换为Java Functional
Interface的实现,这意味着Kotlin进行如下操作:
fun test() = TODO()val exector:Executor = TODO()exector.execute(::test)//::test compile to java pre as below:Runnable task = new Runnable(){ public void run(){ test(); }};为什么
方法引用表达式在Java中可以正常工作,但是在Kotlin中使用函数引用表达式却失败了?
基于上述内容,您可以看到rx-java2中有许多重载
combineLatest方法。例如,以下两个不能正确使用功能引用表达式来制作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>)
就像我说过的那样,Kotlin使用SAM转换将lambda /
函数引用表达式转换为Java Functional
Interface,但是它不能直接分配给Java
Functional
Interface。
combineLatest在Kotlin中方法的第4个参数,编译器根本无法推断其类型,因为第4个参数类型可以是
io.reactivex.functions.Function3或
ObservableSource。因为
ObservableSource它也是Java
功能接口。
当遇到这样的SAM转换冲突时,可以使用将lambda转换为特定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 /
函数引用表达式之前,您必须使用适应,例如:
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())



