【问题标题】:Gradle Kotlin Script, trying to assign classpatch via builtin variableGradle Kotlin Script,尝试通过内置变量分配类补丁
【发布时间】:2020-05-29 12:06:21
【问题描述】:

为什么会这样:

val runVersionSplicer by tasks.registering(type = JavaExec::class) {
    classpath = sourceSets.main.runtimeClasspath // error
    main = "com.concurnas.build.VersionSplicer"
}

返回:

未解决的参考。由于接收器类型不匹配,以下候选均不适用: public val NamedDomainObjectContainer.runtimeClasspath: NamedDomainObjectProvider 定义在 org.gradle.kotlin.dsl

虽然这可以正常工作?

val runVersionSplicer by tasks.registering(type = JavaExec::class) {
    classpath = sourceSets["main"].runtimeClasspath
    main = "com.concurnas.build.VersionSplicer"
}

我知道sourceSets.main是这么定义的:

val org.gradle.api.tasks.SourceSetContainer.`main`: NamedDomainObjectProvider<org.gradle.api.tasks.SourceSet>
    get() = named<org.gradle.api.tasks.SourceSet>("main")

但是不应该替换sourceSets["main"] 构造吗?

【问题讨论】:

    标签: kotlin gradle-kotlin-dsl


    【解决方案1】:

    因为其中一个是提供者,另一个是对象。

    • sourceSets.main 在后台使用NamedDomainObjectCollection.named,正如您发现的那样。如果您查看 named 的 javadoc,您会看到它返回以下内容:

      在查询时将返回对象的 Provider。如果尚未创建和配置对象,则此时可以创建和配置对象

    • sourceSets["main"] 直接返回源集,因为它使用 NamedDomainObjectCollection.getByName 而不是:

      具有给定名称的对象。从不返回 null。

    所以这两个是等价的:

    sourceSets.main.get()
    sourceSets["main"]
    

    在 Groovy 中,以下是等价的:

    sourceSets.main
    sourceSets["main"]
    sourceSets.getAt("main")
    

    这些都是NamedDomainObjectCollection 类实现的getAt 方法的不同语法。这就是为什么您在 Groovy 脚本中看不到很多 get() 而在 Kotlin DSL 脚本中看到更多的原因。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-03-09
      • 1970-01-01
      • 2017-04-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-10-31
      相关资源
      最近更新 更多