kotlin 如何决定 lambda 中的参数名称?

Lyn*_*ynx 2 intellij-idea gradle kotlin

我是 kotlin 新手,我正在尝试开发一个 gradle 插件。当我实现一个名为的 Java 函数接口时,参数名称让我感到困惑org.gradle.api.Action

我的代码。

val action: Action<AppliedPlugin> = Action { // Tip from IDEA "this:AppliedPlugin"
    
}
Run Code Online (Sandbox Code Playgroud)

Java中的函数接口。

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

我对提示感到困惑,因为我认为参数的默认名称it不是this

然后我声明了另一个Java函数接口并实现了它。这次的提示是it:AppliedPlugin!。这是我的代码和临时函数接口。

val temp: Temp<AppliedPlugin> = Temp { // Tip from IDEA "it:AppliedPlugin!"

}
Run Code Online (Sandbox Code Playgroud)
public interface Temp<T> {

    void test(T t);
}
Run Code Online (Sandbox Code Playgroud)

有人可以解释为什么 kotlinthis在第一个 lambda 中使用默认参数名称吗?

Swe*_*per 5

请注意,根据其文档,它org.gradle.api.Action<T>被标记为。的效果正是你可以使用 lambda 参数来引用(大多数时候可以省略):@HasImplicitReceiverHasImplicitReceiverthis

将 SAM 接口标记为 lambda 表达式/闭包的目标,其中单个参数作为调用的隐式接收者传递(this在 Kotlin 中,delegate在 Groovy 中),就好像 lambda 表达式是参数类型的扩展方法一样。

有点像用 Kotlin 编写,即thislambda 参数。

fun interface Action<T> {
    fun T.execute()
}
Run Code Online (Sandbox Code Playgroud)

但上面并不完全一样,因为你只能execute在很少的地方调用,不像Java版本。

这在编写 gradle 插件时很有用,因为必须it.在 build.gradle 中的任何地方键入并不是很好。

请注意,这是 Gradle API 特有的内容。一般来说,在 Kotlin 中,你无法做这样的事情。如果您有这样的 SAM 界面:

public interface Action<T> {
    void execute(T t);
}
Run Code Online (Sandbox Code Playgroud)

lambda 参数始终是it或您指定的其他名称。