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

  • Múltiples requestes de modificación2 usando Flowable en Kotlin
  • Cómo pasar nulo a un Observable con tipo anulable en RxJava 2 y Kotlin
  • No se puede cambiar el text de ActionMenuItemView con RxKotlin
  • No se puede 'observar en' hilo principal con RxKotlin
  • RxJava - ¿Entradas de keyboard de contrapresión?
  • Usando RxJava para unir datos locales con datos remotos (o en caching)
  • RxKotlin collectInto () MutableList usando references de método
  • RxJava- Gire Observable en Iterator, Stream o Sequence
  • Obligatorio <Objeto> y encontrado <Objeto>?
  • ¿Cómo corotines de Kotlin son mejores que RxKotlin?
  • Repetir acciones en estado con RxJava