Behavior with Kotlin higher order functions and single method interfaces?

I had some problems using RxJava and Kotlin before. I made some interesting discoveries that I'm still puzzled about.

RxJava has a simple Func1 interface

 public interface Func1<T, R> extends Function { R call(T t); } 

I tried to add an extension method to Observable , as well as to the RxJava class. This will collect the outliers in the Google Guava ImmutableListMulitmap , using Func1 to display the key for each element.

 fun <K,T> Observable<T>.toImmutableListMultimap(keyMapper: Func1<T, K>): Observable<ImmutableListMultimap<K,T>> { return this.collect({ ImmutableListMultimap.builder<K,T>()},{ b, t -> b.put(keyMapper.call(t), t)}).map { it.build() } } 

When I tried to call this extension method, I could not compile it, and it did not understand the lambda expression at all.

 ScheduledItem.all.flatMap { it.rebuildSoftTransactions } .toImmutableListMultimap { it.id /*compile error */ } .cache() 

However, the strangest thing happened when I modified the extension method to use the type of the function .

 fun <K,T> Observable<T>.toImmutableListMultimap(keyMapper: (T) -> K): Observable<ImmutableListMultimap<K,T>> { return this.collect({ ImmutableListMultimap.builder<K,T>()},{ b, t -> b.put(keyMapper(t), t)}).map { it.build() } } 

And then everything was excellent. But it puzzled me: why didnโ€™t this bring the lambda to the interface? When I use the standard map() method on Observable , it perfectly describes the lambda using the curly brace syntax { } . But why doesn't this work for my extension method above?

+5
source share
1 answer

Converting SAM (converting lambda to function type) currently only works for methods written in Java. Kotlin has corresponding function types, so there is no need to convert SAM - you can declare a parameter as a function type directly (which works, as you noticed).

Observable.map() written in Java, so the SAM transformation is applied. Your extension function is written in Kotlin, so no.

+7
source

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


All Articles