Kotlin 无法将 gradle 的 Action class 转换为 lambda

Kotlin not able to convert gradle's Action class to a lambda

所以,虽然这是针对 gradle 特定问题的 kotlin-dsl,但我认为它总体上适用于 kotlin 语言本身,所以我不会使用该标签。

在gradleAPI中,classAction<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 的 class):

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 inputExpected no parameters。有人可以帮助我了解发生了什么吗?

您需要引用名称为 class 的函数,例如:

val x: Action<String> = Action { println(it) }

这是因为gradle中的Actionclass被注解了HasImplicitReceiver。来自文档:

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.

(强调我的)

所以,下面的编译就好了:

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

你甚至可以只写 ${trim()} 并省略它前面的 this