gradle - 将嵌套闭包调用委托(delegate)给相应的类

标签 gradle kotlin

我正在尝试实现 gradle kotlin 中的插件这将支持这样的结构

env {
    app ("ghc-haskell") {
        srcLink { "http://downloads.haskell.org/~ghc/8.0.1/ghc-8.0.1-x86_64-unknown-mingw32.tar.xz" }
        downloadPath { project(':').projectDir.absolutePath + "\\applications\\plugin" }
        installPath { project(':').projectDir.absolutePath + "\\applications\\plugin" }
    }
}

但是我遇到了像 srcLink 这样的内部闭包的问题。 , downloadPath , installPath .如何将其调用委托(delegate)给相应的kotlin类(class)?

我的扩展看起来像这样
/**
 * Keeps all environments.
 */
open class ApplicationEnvironmentContainerExtension {
    val environs = mutableMapOf<String, ApplicationEnvironmentExtension>()

    fun app(id: String, closure : ApplicationEnvironmentContainerExtension.() -> String) : ApplicationEnvironmentExtension {
        val extension = ApplicationEnvironmentExtension()
        extension.installationId = id
        environs.put(id, extension)
        return extension
    }

    /**
     * Sub extension.
     */
    open class ApplicationEnvironmentExtension {
        var installationId = ""
        var srcLink = ""
        var downloadPath = ""
        var installPath = ""

        fun srcLink(closure: ApplicationEnvironmentExtension.() -> String) {
            srcLink = closure()
        }

        fun downloadPath(closure: ApplicationEnvironmentExtension.() -> String) {
            downloadPath = closure()
        }

        fun installPath(closure: ApplicationEnvironmentExtension.() -> String) {
            installPath = closure()
        }

        override fun toString(): String {
            return "ApplicationEnvironmentExtension(" +
                        "installationId='$installationId', " +
                        "srcLink='$srcLink', " +
                        "downloadPath='$downloadPath', " +
                        "installPath='$installPath')"
        }


    }
}

当我调用我的 print显示环境列表的任务,它只显示设置 installationId - 其他字段为空
open class PrintingTask :  DefaultTask() {

    @TaskAction
    fun print() {
        val extension = this.project.extensions.getByName("env")  as ApplicationEnvironmentContainerExtension

        extension.environs.forEach {
            println(it.value)
        }
    }
}

如何委托(delegate)closure调用 ApplicationEnvironmentExtension ?

最佳答案

您永远不会调用 closure app 中的参数功能。我认为 app 的签名功能是错误的。它应该是这样的:

fun app(id: String, closure: ApplicationEnvironmentExtension.() -> Unit)

这使得 this在关闭时引用 ApplicationEnvironmentExtension .这使得调用 srcLink , downloadPathinstallPath击中正确的物体。

然后通过执行以下操作调用闭包:
val extension = ApplicationEnvironmentExtension()
extension.closure()

这将填充 ApplicationEnvironmentExtension .

我也认为 srcLink 的签名, downloadPathinstallPath功能错误。它们应该这样定义:
 fun srcLink(closure: () -> String)
 fun downloadPath(closure: () -> String)
 fun installPath(closure: () -> String)

关于gradle - 将嵌套闭包调用委托(delegate)给相应的类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41955552/

相关文章:

android - 评估设置 'android' 时出现问题。 gradle.groovy 不存在

android - Gradle-用于发布和调试的不同配置不起作用

android - lateinit 的 isInitialized 属性在伴随对象中不起作用

maven - JRebel 可以在 maven 上的 kotlin-maven-plugin 插件使用时重新加载 Kotlin 类吗?

Kotlin 对象。哪种初始化方式是正确的?

gradle - 如何将基于Gradle的Java应用转换为Maven应用?

flutter - Android 资源链接失败 : fastforward_increment not found

gradle - 在gradle中使用fmpp生成java文件

string - 如何将字符串格式化为电话号码 kotlin 算法

java - 如何让 Javalin 的 Jetty http 服务器绑定(bind)/监听特定地址/端口?