RxKotlin collectInto() MutableList 使用方法引用
RxKotlin collectInto() MutableList using method references
以下代码是我尝试将 RxJava 示例转换为 Kotlin。它应该将一堆 Int
收集到 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
更改为 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,我想知道它是否甚至是一种语言此时的功能?)。非常感谢。
在您的第一个示例中,您尝试将 collect
的方法签名应用于 collectInto
中的方法签名。
这永远行不通,因为 collect
需要一个 Func0<R>
和一个 Action2<R, ? super T>
而 collectInto
需要一个 真实对象 和 BiConsumer<U, T>
.
构造函数 reference 不能用于 collectInto
- 你需要一个真实的对象(例如你的 mutableListOf()
调用)
第二个问题是 Kotlin 需要一个 BiConsumer
对象而不是函数。我不太清楚为什么。显然,Kotlin 无法处理来自 SAM 接口的 lambda 和函数引用的多个泛型。
因此您需要传递 BiConsumer
的一个实例,而不仅仅是一个函数。
这也是为什么我在评论中询问您是否确定错误消息:
range(10, 20).collectInto(mutableListOf(), { l, i -> l.add(i) })
会报错,而
range(10, 20).collectInto(mutableListOf(), BiConsumer { l, i -> l.add(i) })
不会。
以下代码是我尝试将 RxJava 示例转换为 Kotlin。它应该将一堆 Int
收集到 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
更改为 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,我想知道它是否甚至是一种语言此时的功能?)。非常感谢。
在您的第一个示例中,您尝试将 collect
的方法签名应用于 collectInto
中的方法签名。
这永远行不通,因为 collect
需要一个 Func0<R>
和一个 Action2<R, ? super T>
而 collectInto
需要一个 真实对象 和 BiConsumer<U, T>
.
构造函数 reference 不能用于 collectInto
- 你需要一个真实的对象(例如你的 mutableListOf()
调用)
第二个问题是 Kotlin 需要一个 BiConsumer
对象而不是函数。我不太清楚为什么。显然,Kotlin 无法处理来自 SAM 接口的 lambda 和函数引用的多个泛型。
因此您需要传递 BiConsumer
的一个实例,而不仅仅是一个函数。
这也是为什么我在评论中询问您是否确定错误消息:
range(10, 20).collectInto(mutableListOf(), { l, i -> l.add(i) })
会报错,而
range(10, 20).collectInto(mutableListOf(), BiConsumer { l, i -> l.add(i) })
不会。