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/