【问题标题】:Call closure's delegate method from a function in Groovy?从 Groovy 中的函数调用闭包的委托方法?
【发布时间】:2013-07-14 20:44:22
【问题描述】:

在 Gradle 脚本中,我有一个带有委托的 Groovy 闭包,并且我在该委托上创建了一个调用方法的函数,如下所述:

// Simplified example
ant.compressFiles() {
    addFile(file: "A.txt")
    addFile(file: "B.txt")
    addAllFilesMatching("C*.txt", getDelegate())
}

def addAllFilesMatching(pattern, closureDelegate) {
    // ...
    foundFiles.each {
        closureDelegate.addFile(file: it)
    }
}

是否有可能以更漂亮的方式做到这一点,而不必将委托传递给函数?例如,是否可以使用新方法以某种方式扩展委托?

【问题讨论】:

    标签: groovy delegates closures gradle


    【解决方案1】:

    这可以通过创建一个返回Closure的函数来解决:

    ant.compressFiles() addAllFilesMatching("A.txt", "B.txt", "C*.txt")
    
    Closure addAllFilesMatching(String... patterns) {
        // Calculate foundFiles from patterns...
        return {
            foundFiles.each { foundFile ->
                addFile(file: foundFile)
            }
        }
    }
    

    【讨论】:

      【解决方案2】:

      这个怎么样?

      这是对 WillP 答案的微小修改(这是绝对正确的,应该这样做)并且应该更漂亮(根据您的要求),因为它使用闭包而不是方法。

      def addAllFilesMatching = {pattern ->
          // ... foundFiles based on pattern
          foundFiles.each {
              delegate.addFile(file: it)
          }
      }
      
      ant.compressFiles() {
          addFile(file: "A.txt")
          addFile(file: "B.txt")
      
          addAllFilesMatching.delegate = getDelegate() 
          addAllFilesMatching("C*.txt")
      }
      

      【讨论】:

      • delegate.addFile 也可以只是addFile,对吧?虽然它更好,但我仍然认为它在代码复杂性方面没有很大的改进。我希望有一些神奇的方法来让我的函数访问委托(或类似的),但也许没有更好的存在。
      • @DavidPärsson 在闭包中操作delegate 时会有很大的不同。尝试在 Groovy 控制台或 Groovy Web 控制台中 run this sample 看看有什么不同。
      【解决方案3】:

      你可以先声明闭包,设置它的delegateresolveStrategy,然后传递给each

      def addAllFilesMatching(pattern, delegate) {
      
        def closure = {
          addFile file: it
        }
      
        closure.delegate = delegate
        closure.resolveStrategy = Closure.DELEGATE_FIRST
      
        foundFiles = ["a.txt", "b.txt", "c.txt", "d.txt"]
      
        foundFiles.each closure
      }
      

      【讨论】:

      • 这可能行得通,但由于它需要更多代码,而且我仍然需要将委托传递给函数,我真的不认为这符合更漂亮的条件。
      猜你喜欢
      • 2018-10-29
      • 1970-01-01
      • 1970-01-01
      • 2019-10-08
      • 2014-06-20
      • 2013-07-07
      • 2019-06-23
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多