Котлин не может преобразовать класс действий Gradle в лямбду

Так что, хотя это довольно kotlin-dsl для конкретной проблемы, я думаю, что в целом это относится к самому языку kotlin, поэтому я не собираюсь использовать этот тег.

В Gradle API, класс Action<T> определяется как:

@HasImplicitReceiver
public interface Action<T> {
    /**
     * Performs this action against the given object.
     *
     * @param t The object to perform the action on.
     */
    void execute(T t);
 }

Так что в идеале это должно работать в kotlin (потому что это класс с SAM):

val x : Action<String> = {
    println(">> ${it.trim(0)}")
    Unit
}

Но я получаю следующие две ошибки:

Unresolved reference it
Expected Action<String> but found () -> Unit

Чет даже Action<String> = { input: String -> ... } не работает

Теперь вот действительно интригующая часть. Если я делаю следующее в IntelliJ (что, кстати, работает):

object : Action<String> {
    override fun execute(t: String?) {
        ...
    }
}

IntelliJ выскакивает предложение Convert to lambdaчто, когда я делаю, я получаю:

val x = Action<String> {
}

что лучше, но it все еще не решена. Указав это сейчас:

val x = Action<String> { input -> ... }

дает следующие ошибки Could not infer type for input а также Expected no parameters, Может ли кто-нибудь помочь мне с тем, что происходит?

2 ответа

Решение

Это потому что Action класс в Gradle аннотируется HasImplicitReceiver, Из документации:

Помечает интерфейс SAM как цель для лямбда-выражений / замыканий, где единственный параметр передается как неявный получатель вызова (this в Котлине, delegate в Groovy), как если бы лямбда-выражение было методом расширения типа параметра.

(акцент мой)

Итак, следующие компиляции просто отлично:

val x = Action<String> {
    println(">> ${this.trim()}")
}

Вы могли бы даже просто написать ${trim()} и опустить this перед ней.

Вам нужно ссылаться на функцию с именем класса, например:

val x: Action<String> = Action { println(it) }
Другие вопросы по тегам