Kotlin + Rx:需要消费者,找到KFunction

时间:2018-02-12 08:11:29

标签: android kotlin retrofit rx-android

我正在使用Kotlin + Retrofit + Rx。我想将一个请求提取到函数中:

fun getDataAsync(onSuccess: Consumer<Data>, onError: Consumer<in Throwable>) {
    ApiManager.instance.api
            .getData("some", "parameters", "here")
            .subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe(Consumer {
                time = System.currentTimeMillis()
                onSuccess.accept(it)
            }, onError)
}


fun onButtonClick() {
    getDataAsync(this::onSuccess, this::onError)
}

private fun onSuccess(data: Data) {}

private fun onError(throwable: Throwable) {}

我在第getDataAsync(this::onSuccess, this::onError)行中收到错误:

Type mismatch: inferred type is KFunction1<@ParameterName Data, Unit> but Consumer<Data> was expected

Type mismatch: inferred type is KFunction1<@ParameterName Throwable, Unit> but Consumer<in Throwable> was expected

如何解决?

2 个答案:

答案 0 :(得分:2)

问题是,当您提供方法引用时,您的方法getDataAsync需要两个参数类型为Consumer的对象。请注意,Java中也会发生同样的错误。

为了解决这个问题,您既可以将getDataAsync的两个参数都声明为函数引用,也可以创建Consumer的实现。

第一个解决方案

fun getDataAsync(onSuccess: (Data) -> Unit, onError: (Throwable) -> Unit) {

}

fun onButtonClick() {
    getDataAsync(::onSuccess, ::onError)
}


private fun onSuccess(data: Data) {

}

private fun onError(throwable: Throwable) {}

第二种解决方案

fun getDataAsync(onSuccess: Consumer<Data>, onError: Consumer<in Throwable>) {

}

fun onButtonClick() {
    getDataAsync(Consumer { data ->
        // do something
    }, Consumer { throwable ->
        // do something
    })
}

答案 1 :(得分:1)

您可以只传递函数

,而不是将Consumer作为参数传递
fun getDataAsync(onSuccess: (Data) -> Unit, onError: (Throwable) -> Unit) {
     ApiManager.instance.api
        .getData("some", "parameters", "here")
        .subscribeOn(Schedulers.io())
        .observeOn(AndroidSchedulers.mainThread())
        .subscribe({
            time = System.currentTimeMillis()
            onSuccess(it)
        }, onError)
}


fun onButtonClick() {
   getDataAsync(this::onSuccess, this::onError)
}

private fun onSuccess(data: Data) {}

private fun onError(throwable: Throwable) {}