Котлин не может преобразовать класс действий 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) }