TLDR: синтаксис сокращений в вашем конкретном случае:
fetch.enqueue(requests, Func { updatedRequests ->
}, Func { error -> Timber.d("DownloadListActivity Error: %1\$s", error) })
Проблема здесь в том, что вы вызываете функцию, написанную на Kotlin.Вы не можете использовать короткий лямбда-синтаксис здесь, так как Kotlin не будет автоматически превращать лямбды в правильный интерфейс.
"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+) вы можете использовать лямбды в обоих случаях
JavaClass.doWithFunc(string -> System.out.println(string));
KotlinClass.doWithFunc(string -> System.out.println(string));
Это немного сбивает с толку.В настоящее время API-интерфейсы, написанные на Kotlin, предназначенные для потребления Kotlin, должны использовать не функциональные интерфейсы, а фактические параметры функции, то есть для функции 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) })
Недостатком является то, что это дает довольно странный метод для пользователей библиотеки Java, поскольку Kotlin использует его Function1
интерфейс для представления параметров функции.Вам также придется вернуть Unit.INSTANCE
, так как на самом деле это тип в Kotlin.
Fetch enqueue(List<? extends Request>, Function1<? super List<? extends Request>, Unit>, Function1<? super Error, Unit>)