2017-06-15 108 views
2

以下代码是我尝试将RxJava示例转换为Kotlin。它应该收集一堆Int的成MutableList,但我得到了一系列的错误。如果我改变ImmutableList::addImmutableList<Int>::add,我摆脱预期的错误类型参数,它被替换的RxKotlin collectInto()使用方法引用的MutableList

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 

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>) 

这是一个直

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

的错误以下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查看,我想知道它现在是否是语言功能?)。非常感激。

+0

你是否确信你没有得到与lambda相同的错误?因为我明白了...... – Lovis

回答

2

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

这不能工作,因为collect需要一个Func0<R>Action2<R, ? super T>collectInto期望一个实物BiConsumer<U, T>
构造函数参考不能collectInto工作 - 你需要一个真正的对象(例如,您的通话mutableListOf()

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

因此您需要传递一个BiConsumer的实例,而不仅仅是一个函数。
这也是为什么我问的评论无论你是肯定的错误消息:

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

会给我一个错误,而

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

不会。

+0

感谢您的解释。通过一些阅读,我得出了类似的结论,尽管可能不是这样的技术术语!我没有错误;你使用的是什么版本的Kotlin?我有1.1.2-5。 – amb85

+1

[Here's](https://github.com/AshleyByeUK/rxkotlin/blob/6f9bb30c7b1da970c6edb4b11527c29208609056/src/main/kotlin/uk/ashleybye/rxkotlin/operatorstransformations/AdvancedOperators.kt#L107-L130)我充分执行了这个例子。 – amb85

+0

@ amb85我也在用1.1.2-5¯\ _(ツ)_ /¯ – Lovis

相关问题