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í.

  • Llamada asincrónica para cada elemento dentro de una colección
  • Usando RxJava para unir datos locales con datos remotos (o en caching)
  • RxAndroid, cómo detectar si observable ha finalizado la emisión
  • OnComplete nunca se llamó con toSortedList () y groupBy ()
  • Para una function de Kotlin utilizada como expresión, ¿hay una forma concisa de operar y devolver un valor?
  • RxKotlin flattenAsObservable (): no coincide con el método de reference
  • Agregar subscribeOn () está cambiando el tipo de retorno de observable
  • Kotlin con stack RxKotlinFX da un error de class de acceso
  • No se puede 'observar en' hilo principal con RxKotlin
  • ¿Expresar "súper" generics en los types funcionales de Kotlin?
  • Cómo notificar a Observable cuando finalice CountdownTimer