gradle - Gradle Kotlin DSL中的closureOf和delegateClosureOf有什么区别

标签 gradle kotlin closures gradle-kotlin-dsl

The official doc说:

You may sometimes have to call Groovy methods that take Closure arguments from Kotlin code. For example, some third-party plugins written in Groovy expect closure arguments.

In order to provide a way to construct closures while preserving Kotlin’s strong typing, two helper methods exist:

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

Both methods are useful in different circumstances and depend upon the method you are passing the Closure instance into. Some plugins expect simple closures. In other cases, the plugin expects a delegate closure. There sometimes isn’t a good way to tell, from looking at the source code, which version to use. Usually, if you get a NullPointerException with closureOf<T> {}, using delegateClosureOf<T> {} will resolve the problem.



好吧,我没有反对尝试失败修复方法,但也许有一种确定性的方法可以提前告诉使用哪种方法以及为什么?

最佳答案

but maybe there is a deterministic way to tell in advance which method to use



只需检查您正在配置的插件的源代码即可。例如,他们的 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()
  }

根据文档,这比前面的示例复杂得多,因为这显然需要委托(delegate)关闭,然后 delegateClosureOf<T> {}将是合适的选择。

关于gradle - Gradle Kotlin DSL中的closureOf和delegateClosureOf有什么区别,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53653499/

相关文章:

android - travis ci 构建失败 - 原因 : PermGen space

android-studio - 如何从 Codename One 的构建服务器构建原生 Android 源代码

java - Gradle idea插件排除了其他子项目的传递依赖不排除

macos - Android Studio 中无法识别路径变量(无法识别 ndk-build 命令)

kotlin - 为什么 Kotlin 不使用 `List(...)` 作为列表工厂和所有抽象集合的类似约定?

java - Jackson 来自 kotlin 的自定义 json 序列化 java 原语

php - Laravel 向函数传递了额外的参数

closures - 函数闭包与延续,一般和 SML

swift - 同名(和签名)闭包和函数 : non-ambiguous for >0 arguments, 在调用时给予闭包优先权

spring-boot - ./gradle和Spring Boot中的运行有什么区别