当我在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
处有很多错误,其中值updatedRequests
和error
表示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
* */
该问题与基于方法文档的CallBack有关,但我无法使其正常工作!我怎样才能使它完全成为Kotlin并在Kotlin中进行调用?。
该库为Fetch2,用Kotlin编写。我也看不到库中方法的完整代码。
答案 0 :(得分:0)
TLDR:您具体情况下的shorting语法为:
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>)