RxKotlin collectInto () MutableList с использованием ссылок на методы

Следующий код – это моя попытка конвертировать пример RxJava в Kotlin. Предполагается собрать кучу Int 's в MutableList , но я получаю множество ошибок.

 val all: Single<MutableList<Int>> = Observable .range(10, 20) .collectInto(::MutableList, MutableList::add) 

Ошибки:

  Error:(113, 36) Kotlin: Type inference failed: Not enough information to infer parameter T in inline fun <T> MutableList(size: Int, init: (index: Int) -> T): MutableList<T> Please specify it explicitly. Error:(113, 49) Kotlin: One type argument expected for interface MutableList<E> : List<E>, MutableCollection<E> defined in kotlin.collections Error:(113, 67) Kotlin: None of the following functions can be called with the arguments supplied: public abstract fun add(element: Int): Boolean defined in kotlin.collections.MutableList public abstract fun add(index: Int, element: Int): Unit defined in kotlin.collections.MutableList 

Если я изменю ImmutableList::add to ImmutableList<Int>::add , я избавлюсь от ожидаемой ошибки аргумента типа, которая заменяется на:

 Error:(113, 22) Kotlin: Type inference failed: fun <U : Any!> collectInto(initialValue: U!, collector: ((U!, Int!) -> Unit)!): Single<U!>! cannot be applied to (<unknown>,<unknown>) 

Это прямая копия следующего в Java:

 Observable<List<Integer>> all = Observable .range(10, 20) .collect(ArrayList::new, List::add); 

Я понимаю, что первая ошибка говорит мне, что она либо выводит неверный тип, и мне нужно быть более явным (где?), Но я думал, что ::MutableList будет эквивалентом () -> MutableList<Int> . Третья ошибка говорит мне, что она не может вызывать какие-либо из методов add() с аргументами, но опять же, я думал, что MutableList::add эквивалентен { list, value -> list.add(value) } . Четвертая ошибка говорит мне, что не может определить типы, применяемые к collector .

Если вместо этого я использую лямбда-выражение, ошибок нет:

 val all: Single<MutableList<Int>> = Observable .range(10, 20) .collectInto(mutableListOf(), { list, value -> list.add(value) }) all.subscribe { x -> println(x) } 

Я был бы признателен за некоторые комментарии о том, что я делаю неправильно с ссылками на методы, поскольку, очевидно, что-то я неправильно понял (просматривая справочник по языку Котлин , мне интересно, если это даже функция языка в это время?). Очень признателен.

В первом примере вы пытаетесь применить подпись метода collect к той, которая collectInto от collectInto .

Это никогда не может работать, поскольку collect ожидает Func0<R> и Action2<R, ? super T> Func0<R> Action2<R, ? super T> и collectInto ожидает реального объекта и BiConsumer<U, T> .
Ссылка на конструктор не может работать для collectInto – вам нужен реальный объект (например, ваш mutableListOf() )

Вторая проблема заключается в том, что Котлин ожидает объект BiConsumer а не функцию. Я не совсем понимаю, почему. По-видимому, Kotlin не может обрабатывать несколько дженериков для lambdas и ссылки на функцию от SAM-интерфейсов.

Поэтому вам нужно передать экземпляр BiConsumer а не только функцию.
Вот почему я спросил в комментарии, уверены ли вы в сообщении об ошибке:

 range(10, 20).collectInto(mutableListOf(), { l, i -> l.add(i) }) 

даст мне ошибку, в то время как

 range(10, 20).collectInto(mutableListOf(), BiConsumer { l, i -> l.add(i) }) 

не будет.

  • RxKotlin - Single.just () не выделяется при подписке на TestSubscriber
  • Как Kotlin coroutines лучше, чем RxKotlin?
  • Конструктор вложения и объект-компаньон
  • Как указать версию RxJava при использовании RxKotlin?
  • RxJava 2.0 и Kotlin Single.zip () со списком синглов
  • Асинхронный вызов для каждого элемента внутри коллекции
  • Как читать JSON из Url с помощью kotlin Android?
  • RxKotlin flattenAsObservable (): несоответствие типа с ссылкой на метод
  • RxAndroid, Как обнаружить, если наблюдаемое закончило излучение
  • Как я могу условно добавить асинхронную операцию в середине потока RxJava?
  • Как показать диалог «Прогресс» и «Отклонить»
  • Давайте будем гением компьютера.