groovy 中的 apply() 方法语法

apply() method syntax in groovy

在以下语法中:

plugins({
  id('application')
  id 'java'
  id('com.github.johnrengelman.shadow').version('4.0.1')
})
allprojects(
  {
    apply(plugin: 'application')
    apply(plugin: 'java')
    apply(plugin: 'com.github.johnrengelman.shadow')

    repositories({
      mavenCentral()
    })
  }
  ....

  task copyDeps(type: Copy) {
      from (configurations.runtime + configurations.testRuntime) exclude '*'
      into '/tmp'
  } 
)

我的理解是,

apply() 方法正在传递键值 plugin: 'application',其中键是 plugin,值是 'application'

apply()方法的语法方面来看,plugin: 'application'不是可读的语法:

1) 我如何理解这个语法 apply(plugin: 'application')plugin: 'application' 类型 String 的参数是否通过方法 apply() 传递?

2)

语法如下

task copyDeps(type: Copy) {  // Line 54
          from (configurations.runtime + configurations.testRuntime) exclude '*'
          into '/tmp'
      }

写成

tasks.create('copyDeps', Copy, { 
                                from(configurations.runtime + configurations.testRuntime).exclude('*')
                                into(buildDir)
                                }
            )

但给出错误:

FAILURE: Build failed with an exception.

* Where:
Build file '/home/../build.gradle' line: 54

?

这是一个惯用语 groovy "shortcutting"。

apply(plugin: 'application')

可以改写为:

apply( [ plugin: 'application' ] )

意味着 apply() 方法是用 Groovy 地图文字调用的。 地图文字替换 java 的:

Map map = new HashMap();
map.put( "plugin", "application" );

如果作为最后一个参数的方法接受映射,则可以省略方括号。

该行也可以改写为:

apply plugin:'application'

完全没有括号。

更新:

第二题:

是的,它可以(如果它编译)。它看起来很丑但有效。

在Groovy中如果方法的最后一个参数是一个闭包,它可以写成

copyDeps( map ){ }

copyDeps map, {}

或(更多java左右)

copyDeps( map, {} )

更新 2:

根据 ref-doc

tasks.create('copyDeps', Copy, {})task copyDeps(type: Copy) {} 这次在 Gradle 中也可以互换。

tasks.create() 是对 class 属性 的普通方法调用,而 task copyDeps() 代表另一个 Groovy 功能:DSL 构建器 -> 此处Gradle 使用 DSL 生成器。