В чем разница между closureOf и DelegateClosureOf в Gradle Kotlin DSL - PullRequest
0 голосов
/ 06 декабря 2018

В официальном документе написано:

Иногда вам может понадобиться вызвать методы Groovy, которые принимают аргументы Closure из кода Kotlin.Например, некоторые сторонние плагины, написанные на Groovy, ожидают аргументы замыкания.

Чтобы обеспечить способ создания замыканий при сохранении строгой типизации Котлина, существуют два вспомогательных метода:

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

Оба метода полезны в различных обстоятельствах и зависят от метода, в который вы передаете экземпляр Closure.Некоторые плагины ожидают простого закрытия.В других случаях плагин ожидает закрытия делегата.Иногда, не смотря на исходный код, нельзя определить, какую версию использовать.Обычно, если вы получаете NullPointerException с closureOf<T> {}, использование delegateClosureOf<T> {} решит проблему.

Что ж, у меня нет ничего от подхода try-fail-fix, но, возможно, естьдетерминированный способ заранее сказать, какой метод использовать и почему?

1 Ответ

0 голосов
/ 14 июня 2019

но, возможно, существует заранее определенный способ заранее определить, какой метод использовать

Конечно, просто изучив исходный код подключаемого модуля, который вы настраиваете.Например, их пример плагина 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)
}

Это simple 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> {} будетсоответствующий выбор.

...