Gradle Kotlin DSL

时间:2018-12-06 14:23:42

标签: gradle kotlin closures gradle-kotlin-dsl

The official doc说:

  

有时您可能必须调用Groovy方法,该方法从Kotlin代码获取Closure参数。例如,一些用Groovy编写的第三方插件需要闭包参数。

     

为了提供一种在保留Kotlin强类型的同时构造闭包的方法,存在两种辅助方法:

     
      
  • closureOf<T> {}
  •   
  • delegateClosureOf<T> {}
  •   
     

这两种方法在不同情况下都非常有用,并且取决于您将Closure实例传递给的方法。   一些插件期望简单的闭包。   在其他情况下,插件需要委托关闭。   通过查看源代码,有时没有一个很好的方法来告诉您使用哪个版本。通常,如果您将NullPointerExceptionclosureOf<T> {}一起使用,则使用delegateClosureOf<T> {}将解决此问题。

嗯,我再也没有尝试失败修复方法了,但是也许有一种确定性的方法可以预先告诉使用哪种方法以及为什么?

1 个答案:

答案 0 :(得分:1)

  

但是也许有一种确定性的方式可以预先告知要使用哪种方法

只需检查您正在配置的插件的源代码即可。例如,他们的Bintray插件示例为:

bintray {
    pkg(closureOf<PackageConfig> {
        // Config for the package here
    })
}

如果您要检查源代码,则会发现:https://github.com/bintray/gradle-bintray-plugin/blob/master/src/main/groovy/com/jfrog/bintray/gradle/BintrayExtension.groovy#L35..L37

def pkg(Closure closure) {
    ConfigureUtil.configure(closure, pkg)
}

这是一个简单 Closure,因此根据文档,closureOf<T> {}在这里很合适。

现在,他们的另一个示例是在配置服务器场时使用的Gretty插件:

farms {
    farm("OldCoreWar", delegateClosureOf<FarmExtension> {
        // Config for the war here
    })
}

如果您查看源代码,则会发现:https://github.com/akhikhl/gretty/blob/master/libs/gretty-core/src/main/groovy/org/akhikhl/gretty/FarmsConfig.groovy#L23..L32

  void farm(String name = null, Closure closure) {
    if(name == null)
      name = ''
    def f = farmsMap_[name]
    if(f == null)
      f = farmsMap_[name] = createFarm()
    closure.delegate = f
    closure.resolveStrategy = Closure.DELEGATE_FIRST
    closure()
  }

与上一个示例相比,这要复杂得多,并且根据文档,因为这显然希望委托关闭,所以delegateClosureOf<T> {}是合适的选择。