我是kotlin的新手,我正在try 开发一个gradle插件.

我的代码.

val action: Action<AppliedPlugin> = Action { // Tip from IDEA "this:AppliedPlugin"
    
}

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);
}

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

然后我声明了另一个Java函数接口并实现了它.这次小费是it:AppliedPlugin!英镑.这是我的代码和temp函数接口.

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

}
public interface Temp<T> {

    void test(T t);
}

有人能解释一下为什么kotlin在第一个lambda中使用this作为默认参数名吗?

推荐答案

请注意,根据org.gradle.api.Action<T>documentationorg.gradle.api.Action<T>标记为@HasImplicitReceiver.HasImplicitReceiver的作用就是可以使用this引用lambda参数(大多数情况下可以省略):

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

这就像在Kotlin中写这篇文章一样,在这个意义上,this是lambda参数.

fun interface Action<T> {
    fun T.execute()
}

但上述情况并不完全相同,因为与Java版本不同,您只能在很少的地方调用execute.

这在编写gradle插件时很有用,因为在构建的任何地方都必须键入it..格拉德尔不是很好.

请注意,这是GradleAPI特有的.一般来说,在Kotlin ,你不能做这样的事情.如果您有这样的SAM接口:

public interface Action<T> {
    void execute(T t);
}

lambda参数始终为it,或您指定的其他名称.

Kotlin相关问答推荐

在Kotlin 有更好的结合方式?

Kotlin编译器如何决定是否可以在任何给定点调用Suspend方法?

为什么我的通用Kotlin函数中的这个转换未经判断?

ActivityResultContracts TakePicture 结果总是返回 false

如何创建扩展函数isNullOrEmpty?

如果不为空,则为 builder 设置一个值 - Kotlin

KMM:编译失败:意外的 IrType 类型:KIND_NOT_SET

如何在 Kotlin 中实现 Composition UML 关系?

类型不匹配:Required: Context, Found: Intent

Android 导航组件 - 向上导航打开相同的片段

在 Kotlin 中,当枚举类实现接口时,如何解决继承的声明冲突?

将 Gradle 子元素与 Kotlin 多平台一起使用

Kotlin boxed Int 不一样

无法在Kotlin中使用argb color int值?

禁用 IntelliJ kotlin * 导入?

Kotlin内联属性的用例是什么?

如何在不绑定ViewModel(MVVM)中的UI的情况下使用android导航?

Kotlin:在何时使用枚举

Android studio,构建kotlin时出现奇怪错误:生成错误代码

Kotlin:如何使用扩展函数扩展枚举类