groovy编译器对gradle的解释是什么?取决于语法

时间:2019-05-18 19:56:30

标签: gradle groovy

我了解gradle DSL

task doTask { logger.info "some text" }

实际上将在Project委托对象上调用方法task(String,Closure)。

task("doTaks", {logger.info("some text")})

很好。但是,当我尝试了解一些在第三方构建脚本中看到的gradle DSL语法时,事情就变得复杂了:

task doTask (dependsOn: 'otherTask'){logger.info "some text"}

我认为groovy将通过(dependsOn:'otherTask')创建地图,并以某种方式使用Project方法

task(Map args, String name, Closure config)

将被调用。但是这些额外的括号是如何起作用的,为什么它们是必需的,groovy如何找到我们想要的东西呢?以我最低的常规技巧,该语法对我来说似乎完全违反直觉。我永远不会猜到我必须通过这种方式才能使它工作。

所以,这就是问题:groovy如何弄清楚该命令的作用:

task doTask (dependsOn: 'otherTask'){ // some code }

1 个答案:

答案 0 :(得分:1)

您可以使用以下语法之一来调用groovy方法:

  1. Args必须在圆括号内用逗号分隔:

    method(arg1, arg2, ..., argN, argClosure)
    
  2. Args必须全部用逗号分隔,且不带括号:

    method arg1, arg2, ..., argN, argClosure
    
  3. 如果最后一个参数为闭包,则所有先前的args必须在圆括号内全部用逗号分隔,并且圆括号后的代码块(在大括号{...}中)将被解释为最后一个{{ 3}}自变量argClosure

    method(arg1, arg2, ..., argN) { ... }
    

    如果您不要,希望花括号中的代码块被解释为先前方法调用的Closure参数;然后以分号结束方法调用:

    // Because of `;` following { ... } is not a Closure argument for `method`
    method(arg1, arg2, ..., argN); { ... }
    
  4. 可以使用Closure语法来调用一个接受单个MapMap和一个闭包作为参数的方法。它将把每个 named 参数转换为映射中的一个条目,最后一个参数将是一个闭包。这将创建以下直观的语法变体:

    method(name1: arg1, name2: arg2, ..., nameN: argN, argClosure)
    method name1: arg1, name2: arg2, ..., nameN: argN, argClosure
    method(name1: arg1, name2: arg2, ..., nameN: argN) { ... }
    

Groovy提供大量的语法糖,因此可以在此周围找到其他直观的变体。但这会让您感觉到Groovy处理Closure参数的方式。

以下是进行方法调用的这些不同方法的工作演示:

import java.time.LocalDateTime

def handleWithClosure(data1, data2, closure) {
    closure("$data1. $data2")
}

def logger = { println "${LocalDateTime.now()} - $it" }
handleWithClosure(1, 'All within parenthesis', logger)
handleWithClosure 2, 'All without parenthesis', logger
handleWithClosure(3, 'List of arguments within parenthesis and closure outside') { logger(it) }

def handleMapWithClosure(map, closure) {
    handleWithClosure(map['num'], "[Named Arguments/Map based] ${map['msg']}", closure)
}

handleMapWithClosure(msg: 'All within parenthesis', num: 1, logger)
handleMapWithClosure msg: 'All without parenthesis', num: 2, logger
handleMapWithClosure(msg: 'List of arguments within parenthesis and closure outside', num: 3) { logger(it) }

运行它,您可以看到它如何处理所有这些语法选项。

希望这会有所帮助。