使用方法引用的RxKotlin collectInto()MutableList

时间:2017-06-15 22:54:48

标签: kotlin method-reference rx-kotlin

以下代码是我尝试将RxJava示例转换为Kotlin。它应该收集一堆IntMutableList,但是我收到了很多错误。

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更改为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的类型。

如果我使用lambda表达式,则没有错误:

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

all.subscribe { x -> println(x) }

我很欣赏一些关于我在方法参考上做错的评论,因为显然我误解了一些内容(通过Kotlin Language Reference查看,我想知道它是否甚至是语言功能这次?)。非常感谢。

1 个答案:

答案 0 :(得分:3)

在第一个示例中,您尝试将collect的方法签名应用于collectInto中的方法签名。

这可能永远不会有效,因为collect期望Func0<R>Action2<R, ? super T>以及collectInto期望真实对象和{{1} }}。
构造函数引用不适用于BiConsumer<U, T> - 您需要一个真实的对象(例如您的collectInto调用)

第二个问题是Kotlin期待一个mutableListOf()对象而不是一个函数。我不太清楚为什么。显然,Kotlin无法处理来自SAM-Interfaces的lambdas和函数引用的多个泛型。

因此,您需要传递BiConsumer的实例而不仅仅是函数 这也是我在评论中询问您是否确定错误消息的原因:

BiConsumer

会给我一个错误,而

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

赢得&#39;吨。