Comportamiento con Kotlin Higher-Order Functions e interfaces de método único?

Estaba teniendo problemas al usar RxJava y Kotlin anteriormente. Hice algunos descubrimientos interesantes sobre los que todavía estoy desconcertado.

Existe la interfaz simple Func1 en RxJava

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

Estaba intentando agregar un método de extensión a un Observable , también una class RxJava. Esto recogería las emisiones en un map de Func1 Google Guava utilizando un Func1 para mapear la key de cada elemento.

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

Cuando traté de invocar este método de extensión, no pude hacer que comstackra, y no entendía la expresión lambda en absoluto.

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

Sin embargo, lo más extraño sucedió cuando modifiqué el método de extensión para usar el tipo de 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() } } 

Y luego todo compiló bien. Pero esto es lo que me dejó perplejo: ¿cómo es que no infería el lambda en la interfaz? Cuando uso el método estándar map() en el Observable , infiere lambda simplemente usando la syntax { } corchete. Pero, ¿por qué no funciona para mi método de extensión anterior?

La conversión SAM (convertir un lambda en un tipo de function) actualmente funciona solo para los methods escritos en Java. Kotlin tiene types de funciones adecuados, por lo que no es necesario realizar una conversión SAM: puede declarar directamente el parámetro como un tipo de function (que funciona, como ha observado).

Observable.map() está escrito en Java, por lo que se aplica la conversión SAM. Su function de extensión está escrita en Kotlin, por lo que no es así.

  • RxJava (Kotlin), Observable.amb y PublishSubject no están disparando
  • OnComplete nunca se llamó con toSortedList () y groupBy ()
  • RxKotlin - Single.just () no se emite al suscribirse TestSubscriber
  • Cómo comprimir algunos observables en lenguaje Kotlin con RxAndroid
  • ¿Cómo hacer un grupo? ¿Por qué coleccionar usando RxJava y Kotlin?
  • ¿Cómo leer JSON desde Url usando kotlin Android?
  • RxJava2 Tal vez devuelva Observable vacío si no hay elemento
  • Excepción causada por: java.lang.ClassNotFoundException: org.reactivestreams.Publisher
  • Kotlin con stack RxKotlinFX da un error de class de acceso
  • ¿Cómo especificar la versión de RxJava al usar RxKotlin?
  • ¿Cómo puedo agregar de manera condicional una operación asincrónica en medio de una transmisión de RxJava?