【问题标题】:I have a problem after Java to Kotlin conversion with the error in Android Studio, Cannot infer a type for this parameterJava 到 Kotlin 转换后出现问题,Android Studio 中出现错误,无法推断此参数的类型
【发布时间】:2018-10-12 22:24:13
【问题描述】:

当我在 Java 中转换此方法时:

private void enqueueDownloads() {
    final List<Request> requests = Data.getFetchRequestWithGroupId(GROUP_ID);
    fetch.enqueue(requests, updatedRequests -> {

    }, error -> Timber.d("DownloadListActivity Error: %1$s", error.toString()));

}

导致这个方法有很多错误:

private fun enqueueDownloads() {
    val requests = Data.getFetchRequestWithGroupId(GROUP_ID)
    fetch.enqueue(requests, { updatedRequests ->

    }, { error -> Timber.d("DownloadListActivity Error: %1\$s", error.toString()) })

}

Kotlin 中的这个方法在 fetch.enqueue 方法中有很多错误,其中值 updatedRequestserror 表示 Cannot infer a type for this parameter

所以我将鼠标悬停在方法上并点击Ctrl+B,库中的方法声明是:

fun enqueue(requests: List<Request>, func: Func<List<Request>>? = null, func2: Func<Error>? = null): Fetch

/** Pause a queued or downloading download.
 * @param ids ids of downloads to be paused.
 * @param func Callback the paused downloads will be returned on. Note. Only downloads that
 * were paused will be returned in the result list.
 * @param func2 Callback that is called when attempting to pause downloads fail. An error is returned.
 * @throws FetchException if this instance of Fetch has been closed.
 * @return Instance
 * */

问题与基于方法文档的回调有关,但我无法让它工作!我怎样才能使它完全 Kotlin 并在 Kotlin 中调用它?。

库是Fetch2,用 Kotlin 编写。我也看不到库中方法的完整代码。

【问题讨论】:

  • Func 是 kotlin 接口吗?您需要 kotlin 中又长又丑的 object : Func&lt;List&lt;String&gt;&gt; { override fun xyz(list: List&lt;String&gt;) { .. }} 语法来实现 kotlin 接口。漂亮的短 lambda 语法仅适用于 java 接口。 kotlinlang.org/docs/reference/java-interop.html#sam-conversions “Kotlin 有正确的函数类型,将函数自动转换为 Kotlin 接口的实现是不必要的,因此不受支持。” :)
  • 您需要创建一个minimal reproducible example。您没有指定库,也没有在问题中添加必要的类/接口,因此很难在没有猜测的情况下回答。
  • 好的,现在我已经添加了库名称和链接@Zoe,但我无法访问所有源代码。
  • 接口是Java接口,所以不需要长版(直接使用lambda即可)。您可以尝试强制参数。
  • 原来你的评论是救命稻草。非常感谢@zapl,我会给你一张去天堂的票。去然后返回。

标签: java android android-studio kotlin fetch2


【解决方案1】:

TLDR:在您的具体情况下,shortes 语法是:

fetch.enqueue(requests, Func { updatedRequests ->

}, Func { error -> Timber.d("DownloadListActivity Error: %1\$s", error) })

这里的问题是您正在调用用 Kotlin 编写的函数。此处不能使用短 lambda 语法,因为在这种情况下 Kotlin 不会自动将 lambda 转换为正确的接口。

“Kotlin 具有正确的函数类型,将函数自动转换为 Kotlin 接口的实现是不必要的,因此不受支持。” (source)

通常要在 Kotlin 中匿名实现 (Kotlin) 接口,您必须使用成熟的对象语法:

interface KFunc<T> { fun call(result: T) }

val func = object : KFunc<String> {
    override fun call(result: String) {
        println(result)
    }
}

不过Func 是用 Java 定义的接口,所以 Kotlin 提供了一个自动转换实用程序,您可以编写

val func: Func<String> = Func {
    result -> println(result)
}

这是因为每个 Java 接口都有一个自动生成的方法。在这种情况下,将生成以下代码

fun <T> Func(function: (result: T) -> Unit): Func<T> {
    return object : Func<T> {
        override fun call(result: T) {
            function(result) // call the function
        }
    }
}

如果采用Func 的方法也是用Java 编写的,那么您甚至可以省略Func {} 部分。例如。给定

public class JavaClass {
    public static void doWithFunc(Func<String> func) {
         func.call("Hello");
    }
}

你可以写

JavaClass.doWithFunc { result -> println(result) }

不管怎样

object KotlinClass {
    @JvmStatic
    fun doWithFunc(func: Func<String>) {
        func.call("Hello")
    }
}

你必须至少写

KotlinClass.doWithFunc(Func { result -> println(result) })

另一方面,来自 Java(8+) 你可以在这两种情况下使用 lambdas

JavaClass.doWithFunc(string -> System.out.println(string));
KotlinClass.doWithFunc(string -> System.out.println(string));

这有点令人困惑。目前,用 Kotlin 编写的供 Kotlin 使用的 API 不应该使用函数式接口,而是使用实际的函数参数,即 enqueue 函数

fun enqueue(requests: List<Request>, func: Func<List<Request>>? = null, func2: Func<Error>? = null): Fetch

理想情况下,他们也会提供

fun enqueue(requests: List<Request>, func: ((List<Request>) -> Unit)? = null, func2: ((Error) -> Unit)? = null): Fetch

这将允许您像在 Kotlin 中所期望的那样调用它

fixedFetch.enqueue(requests, { println(it) }, { Timber.w(it) })

缺点是因为 Kotlin 使用它的 Function1 接口来表示函数参数,所以这为库的 Java 用户提供了一种相当奇怪的方法。您还必须返回 Unit.INSTANCE,因为这实际上是 Kotlin 中的一种类型。

Fetch enqueue(List<? extends Request>, Function1<? super List<? extends Request>, Unit>, Function1<? super Error, Unit>)

【讨论】:

    猜你喜欢
    • 2017-10-30
    • 2019-09-05
    • 1970-01-01
    • 2014-08-01
    • 2023-01-26
    • 2016-02-15
    • 1970-01-01
    • 1970-01-01
    • 2021-12-31
    相关资源
    最近更新 更多