kotlin - Gradle 扩展 : can plain Kotlin types be used instead of Property<T> for properties with simple values?

标签 kotlin gradle gradle-plugin gradle-kotlin-dsl

Gradle docs for lazy configuration指出在扩展/DSL 类中,属性如 var someProperty = "default value"实际上应该是val someProperty: Property<String> = objectFactory.property(String::class.java).convention("default value") 。这是为了避免配置阶段不必要的计算;

我想知道对简单值使用普通类型是否有任何缺点。在计算或 I/O 的情况下,好处对我来说是显而易见的,但如果有的话,对于简单的值,我会说普通类型会导致配置期间的资源使用稍微少一些(少创建一个对象,并且没有方法调用)。

我更喜欢简单值的普通属性类型的主要原因是简单,尤其是赋值运算符可以在具有 Kotlin DSL 的构建脚本中使用,例如someProperty = "foo" 。我发现这比 someProperty.set("foo") 更干净后者也是命令式的,而 Gradle DSL 在其他方面大多是声明性的。

它似乎工作正常,并且在任务中仍然会有 Property<String>可以用 someProperty.set(extension.someProperty) 初始化的对应项,但由于文档没有提到它作为简单值的可能性,我想知道是否有一个我想不到的充分理由。

最佳答案

除了在配置阶段避免不必要的计算之外,使用属性还可以让您避免使用 afterEvaluate 子句的竞争条件。构建脚本设置的扩展值在配置时不可用。

因此,您的示例 task.someProperty.set(extension.somePlainField)不会工作。

使用task.someProperty.set(extension.someProperty) (带有签名 set(value: Provider<T>) 的方法)确保 extension.someProperty.get()在任务执行并读取其属性之前不会调用。

为了实现流畅的扩展 api 的目标,建议的方法是向您的扩展添加一个方法,例如

fun someProperty(value: String) {
  someProperty.set(value)
}

然后,构建脚本可以像这样使用它:

myExtension {
  someProperty("my value")
}

关于kotlin - Gradle 扩展 : can plain Kotlin types be used instead of Property<T> for properties with simple values?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/73479805/

相关文章:

java - 任务:compileJava FAILED -> gradlew bootRun

sql - 如何获取最后插入的ROW SQL(非ID)Jooq

java - 在 Kotlin 项目中包含使用 Java9 或 Java10 构建的 Maven 依赖项

java - 错误 : Could not find com. android.tools.build :gradle:3. 5.2

java - 从另一个配置附加依赖项

java - 如何将我的 Gradle 插件中的任务执行链接到另一个插件的输出文件?

java - 在Gradle中的AspectJ插件中使用方面库

Gradle sonarqube 插件 - 如何为 findbugs 设置内存?

kotlin - KDoc 中的表?

javafx - 无法使用 TornadoFX 将节点置于 StackPane 中心