Wcześniej miałem problemy z RxJavą i Kotlinem. Zrobiłem kilka interesujących odkryć, o których wciąż jestem zaskoczony.Zachowanie z funkcjami wyższego rzędu w kotlinach i interfejsami opartymi na pojedynczej metodzie?
Istnieje prosty interfejs Func1
w RxJava
public interface Func1<T, R> extends Function {
R call(T t);
}
Próbowałem dodać metodę rozszerzenia do Observable
, również klasy RxJava. To by zbierało emisje do Google Guava ImmutableListMulitmap
używając Func1
, aby odwzorować klucz z każdego przedmiotu.
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() }
}
Kiedy próbowałem wywołać tę metodę rozszerzenia nie mogę zmusić go do kompilacji, a nie było zrozumienia wyrażenia lambda w ogóle.
ScheduledItem.all.flatMap { it.rebuildSoftTransactions }
.toImmutableListMultimap { it.id /*compile error */ } .cache()
Jednak najdziwniejsze stało, kiedy zmodyfikował metodę rozszerzenia do korzystania z function type.
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() }
}
A następnie wszystko skompilowane dobrze. Ale to mnie zaintrygowało: dlaczego to nie wpłynęło na interfejs lambda? Kiedy używam standardowej metody map()
na Observable
, to w łatwy sposób uzyskujemy lambdę, używając składni nawiasów klamrowych { }
. Ale dlaczego nie działa dla mojej metody rozszerzenia powyżej?