Gradle三种任务定义形式原理疑问:后两种为何可正常工作?
Gradle三种任务定义形式的原理解析
这三种在build.gradle中定义任务的写法,最终都会调用org.gradle.api.internal.project.DefaultProject#task(java.lang.String, groovy.lang.Closure)方法,但很多人会困惑第二种和第三种的工作逻辑,先看代码示例:
def myAction = {t -> println "${t.name} [${t.class.name}]"} // 形式A:带引号与括号的标准调用 task('myTaskA') {task -> group = 'MyTasks' description = name doLast myAction } // 形式B:无引号无括号的简洁写法 task myTaskB {task -> group = 'MyTasks' description = name doLast myAction } // 形式C:无引号但带空括号的写法 task myTaskC() {task -> group = 'MyTasks' description = name doLast myAction }
本质:Groovy的语法糖
Gradle基于Groovy语言,这三种写法的差异完全来自Groovy的语法特性,核心都是调用project.task()方法:
形式A:最直观的标准方法调用,把任务名以字符串形式作为第一个参数传入,后面的闭包是第二个参数,用来配置任务的分组、描述、执行逻辑等。
形式B:Groovy允许当方法的第一个参数是符合标识符规则的字符串时,省略括号和引号。也就是说
task myTaskB { ... }等价于task('myTaskB', { ... })——Groovy会自动把myTaskB识别为字符串参数,同时把后续闭包作为第二个配置参数传递给task方法。形式C:和形式B逻辑一致,只是多写了一对空括号。Groovy中调用方法时,空括号可以省略,但这里显式写出也不影响逻辑,最终还是等价于
task('myTaskC', { ... }),把myTaskC作为任务名字符串,闭包作为配置参数传入。
关键结论
这三种写法没有功能差异,只是Groovy语法糖带来的不同书写形式,最终都会被解析为相同的方法调用,完成任务的定义与配置。
内容的提问来源于stack exchange,提问作者ninopg
相关产品推荐
相关产品推荐

