Gradle Kotlin 脚本,试图通过内置变量分配类补丁
Gradle Kotlin Script, trying to assign classpatch via builtin variable
为什么这样:
val runVersionSplicer by tasks.registering(type = JavaExec::class) {
classpath = sourceSets.main.runtimeClasspath // error
main = "com.concurnas.build.VersionSplicer"
}
returns:
Unresolved reference. None of the following candidates is applicable because of receiver type mismatch:
public val NamedDomainObjectContainer.runtimeClasspath: NamedDomainObjectProvider defined in 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"]
构造?
因为其中一个是提供者,另一个是对象。
正如您所发现的,sourceSets.main
在幕后使用了 NamedDomainObjectCollection.named
。如果您查看 named
的 javadoc,您会看到它 returns 以下内容:
A Provider that will return the object when queried. The object may be created and configured at this point, if not already
sourceSets["main"]
returns源直接设置,因为它使用NamedDomainObjectCollection.getByName
代替,whi:
The object with the given name. Never returns null.
所以这两个是等价的:
sourceSets.main.get()
sourceSets["main"]
在Groovy中以下是等价的:
sourceSets.main
sourceSets["main"]
sourceSets.getAt("main")
NamedDomainObjectCollection
class 实现的getAt
方法的不同语法。这就是为什么您在 Groovy 脚本中看不到很多 get()
但在 Kotlin DSL 脚本中看到很多的原因。
为什么这样:
val runVersionSplicer by tasks.registering(type = JavaExec::class) {
classpath = sourceSets.main.runtimeClasspath // error
main = "com.concurnas.build.VersionSplicer"
}
returns:
Unresolved reference. None of the following candidates is applicable because of receiver type mismatch: public val NamedDomainObjectContainer.runtimeClasspath: NamedDomainObjectProvider defined in 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"]
构造?
因为其中一个是提供者,另一个是对象。
-
正如您所发现的,
sourceSets.main
在幕后使用了NamedDomainObjectCollection.named
。如果您查看named
的 javadoc,您会看到它 returns 以下内容:A Provider that will return the object when queried. The object may be created and configured at this point, if not already
sourceSets["main"]
returns源直接设置,因为它使用NamedDomainObjectCollection.getByName
代替,whi:The object with the given name. Never returns null.
所以这两个是等价的:
sourceSets.main.get()
sourceSets["main"]
在Groovy中以下是等价的:
sourceSets.main
sourceSets["main"]
sourceSets.getAt("main")
NamedDomainObjectCollection
class 实现的getAt
方法的不同语法。这就是为什么您在 Groovy 脚本中看不到很多 get()
但在 Kotlin DSL 脚本中看到很多的原因。