Intereting Posts
Котлинский шаблон для использования Spring Data JPA «запрос по примеру» Intellij IDEA не добавляет зависимости maven к пути класса kotlin script classpath Каково использование сопутствующего объекта в котлине и замена в java Напиши Скопируемый интерфейс более элегантный, чем в Java Создание публичного экземпляра частного внутреннего класса в Котлине Расширение классов в дженериках Котлина Это плохая практика поиска данных в списке по индексу несколько раз? Как я могу использовать базу данных пользовательского интерфейса Firebase с Kotlin Преобразование строки, полученной из edittext в Integer на языке Котлин Каков самый умный способ скопировать карту в Котлин? Kotlin – Operator '==' не может применяться к «Редактируемому!». и 'String' при сравнении строки Как изменить префикс последовательности Kotlin, но сохранить хвост? Пользовательский Джерси ExceptionMapper весной Boot с kotlin Имущество должно быть инициализировано или быть абстрактным Общее литье в Котлине

Ссылка конструктора Котлина с дженериками

У меня этот код в (Rx) Java:

Observable.fromArray(1, 2, 3) .flatMap(this::intToBooleanObservable, Pair::new) ..... 

Я бы ожидал, что соответствующий код Котлина будет выглядеть так:

 Observable.fromArray(1, 2, 3) .flatMap(::intToBooleanObservable, ::Pair) ..... 

Однако компилятор не может вывести общий тип пары, поэтому лучшее, что я могу сделать сейчас, это:

 .flatMap(::intToBooleanObservable, { a, b -> a to b }) 

Это не так лаконично, как хотелось бы.

Есть ли способ достичь этого, не объявляя переменные a и b ?

Та же проблема здесь. Несколько других обходных решений (в том порядке, в котором я их использовал), вам может понравиться один из них.

1) Написание собственного оператора:

 fun <T, U> Single<T>.flatMapPair(func: (T) -> Single<U>) : Single<Pair<T, U>> { return this.flatMap { t -> func.invoke(t).map { u -> t to u } } } 

2) Переместите обертывание в условное Observable (здесь intToBooleanObservable), возвращая результат в виде пары или более явный и настраиваемый тип (закрытый класс с двумя дочерними элементами, например «Успех и сбой»). Это позволяет использовать более явный код:

  when(it) { is Success -> ... is Failure -> ... } 

3) В зависимости от результата intToBooleanObservable у вас теперь есть 2 разных сценария (я полагаю). Обычно это своего рода отказ / отказ, быстро решаемый. Для этого напишите фильтр с побочным эффектом, где предикат является наблюдаемым, тем самым избегая проблемы:

 fun <T> Observable<T>.filterSingle(predicate: (T) -> Single<Boolean>, rejectionFunction: (T) -> Unit): Observable<T> = ... //filter with the given predicate, and call rejectionFunction if item doesn't pass 

4) Последний метод работает только с логическим результатом. Что, если меня интересует причина отказа / отказа дать содержательное сообщение? Ради однородного кода я сбросил этот оператор. Вдохновленный другими языками функционалов, я определил один тип и определенные общие операторы Aither + RxJava; mapRight, flatMapRight и более важный dropLeft. dropLeft – это как обобщение filterSingle.

 inline fun <L, R> Observable<Either<L, R>>.dropLeft(crossinline sideEffect: (L) -> Unit): Observable<R> = this.lift { downObserver -> object: Observer<Either<L, R>> { override fun onError(throwable: Throwable?) = downObserver.onError(throwable) override fun onSubscribe(disposable: Disposable?) = downObserver.onSubscribe(disposable) override fun onComplete() = downObserver.onComplete() override fun onNext(either: Either<L, R>) = when (either) { is Right -> downObserver.onNext(either.value) is Left -> sideEffect(either.value) } } } 

Надеюсь, это поможет.