问题
So, while this is quite a kotlin-dsl for gradle specific issue, I think it overall applies to the kotlin language itself, so I am not going to use that tag.
In the gradle API, the class Action<T>
is defined as:
@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);
}
So ideally, this should work in kotlin (because it is a class with a SAM):
val x : Action<String> = {
println(">> ${it.trim(0)}")
Unit
}
But I get the following two errors:
Unresolved reference it
Expected Action<String> but found () -> Unit
Fwiw, even Action<String> = { input: String -> ... }
doesn't work.
Now here's the really intriguing part. If I do the following in IntelliJ (which btw, works):
object : Action<String> {
override fun execute(t: String?) {
...
}
}
IntelliJ pops the suggestion Convert to lambda
, which when I do, I get:
val x = Action<String> {
}
which is better, but it
is still unresolved. Specifying it now:
val x = Action<String> { input -> ... }
gives the following errors Could not infer type for input
and Expected no parameters
. Can someone help me with what is going on?
回答1:
This is because the Action
class in gradle is annotated with HasImplicitReceiver. From the documentation:
Marks a SAM interface as a target for lambda expressions / closures where the single parameter is passed as the implicit receiver of the invocation (
this
in Kotlin,delegate
in Groovy) as if the lambda expression was an extension method of the parameter type.
(emphasis mine)
So, the following compiles just fine:
val x = Action<String> {
println(">> ${this.trim()}")
}
You could even just write ${trim()}
and omit the this
in front of it.
回答2:
You need reference the function with class name, like:
val x: Action<String> = Action { println(it) }
来源:https://stackoverflow.com/questions/47908148/kotlin-not-able-to-convert-gradles-action-class-to-a-lambda