kotlin - Gradle 的 Kotlin DSL 中令人困惑的属性委托(delegate)

标签 kotlin gradle gradle-kotlin-dsl

下面是我在 gradle 文档中遇到的代码片段 <强> https://docs.gradle.org/current/userguide/tutorial_using_tasks.html

val hello by tasks.registering {
    doLast {
        println("Hello Earth")
    }
}
hello {
    doFirst {
        println("Hello Venus")
    }
}

在上面,hello是一个TaskProvider类型,它提供任务定义/操作。对 hello 的第二次调用是扩展任务的行为。

这个委托(delegate)的使用对我来说看起来有点令人困惑。以下是困扰我的问题:

1) 在检查反编译的字节码时,我看到 tasks.registering 返回 RegisteringDomainObjectDelegateProviderWithAction 对象,该对象应该用作委托(delegate),因此应该提供 getValue() 和委托(delegate)的 setValue() 方法可以正常工作,但正如我所见,没有提供方法。相反,RegisteringDomainObjectDelegateProviderWithAction 类具有 tasks 类型的 delegateProvider 属性,该属性应该提供委托(delegate)。任何人都可以帮助我理解委托(delegate)是如何工作的吗?

2) 第二次调用应该向 hello 任务添加行为。由于 hello 是一个属性,我们如何向它传递 lambda/行为?我错过了什么?

我已经看过 kotlin 文档,它对委托(delegate)提供了很好的解释,但无助于理解上述情况 https://kotlinlang.org/docs/reference/delegated-properties.html

由于我是 Kotlin 新手,因此希望能得到详细的解释。

最佳答案

  1. 关于委托(delegate)的使用:

    委托(delegate)通过扩展运算符方法进行工作 provideDelegate定义于RegisteringDomainObjectDelegateProviderWithAction :

    operator fun RegisteringDomainObjectDelegateProviderWithAction<out TaskContainer, Task>.provideDelegate(
        receiver: Any?,
        property: KProperty<*>
    ) = ExistingDomainObjectDelegate.of(
        delegateProvider.register(property.name, action)
    )
    

    provideDelegate运算符允许在委托(delegate)创建中使用更复杂的逻辑。根据docs :

    By defining the provideDelegate operator you can extend the logic of creating the object to which the property implementation is delegated. If the object used on the right hand side of by defines provideDelegate as a member or extension function, that function will be called to create the property delegate instance.

  2. 关于“将 lambda 传递给属性”:

    这是通过重载 invoke operator 来实现的作为 TaskProvider 上的扩展函数类:

    operator fun <T> NamedDomainObjectProvider<T>.invoke(action: T.() -> Unit) =
        configure(action)
    

    基本上,调用 hello { /* your lambda */ }脱糖为hello.invoke { /* your lambda */ } .

关于kotlin - Gradle 的 Kotlin DSL 中令人困惑的属性委托(delegate),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61263667/

相关文章:

android - 如何在 kotlin android 中共享 .txt 文件

kotlin - 科廷 : Is `until` and `..` just a syntax difference?

java - 有没有办法将 jar 库指向与 tomcat 8 中的 war 不同的位置以减少 war 规模?

android - 使用classloader AntClassLoader []无法找到taskdef类org.apache.tools.ant.taskdefs.optional.ssh.Scp。

gradle - 错误:无法在Jar中找到或加载主类

arrays - 打印一个简单的数独板阵列

json - Spring Boot 在 json 中包含 ID 字段

Android 和 Fabric (Crashlytics) 插件总是生成一个 UUID (Gradle Kotlin DSL)

gradle - 升级到 gradle-5 后,war 文件很大

kotlin - 来自 groovy 的 kotlin 中的数组列表