【问题标题】:Groovy Closure explanationGroovy 闭包解释
【发布时间】:2013-06-12 19:26:28
【问题描述】:

我熟悉像这样的普通的 groovy 闭包

def printSum = {a,b ->
   println a+b
}

printSum(5,7) // 12

但是,我从 SpringWS 插件中发现了我很难理解的代码:

def withEndpointRequest = { url, payload ->
    def writer = new StringWriter()
    def request = new MarkupBuilder(writer)
    payload.delegate = request
    payload.call()
    def webServiceTemplate = new WebServiceTemplate()

    def response = webServiceTemplate.sendToEndpoint(url, writer.toString())
    new XmlSlurper().parseText(response)
}

我知道上面是一个闭包。

它是这样使用的:

    def namespace = "http://www.myveryimportantcompany.com/hr/schemas"
    def serviceURL = "http://localhost:8080/myapp/services"
    def response = withEndpointRequest(serviceURL) {
        HolidayRequest(xmlns: namespace) {
            Holiday {
                StartDate("2006-07-03")
                EndDate("2006-07-07")
            }
            Employee {
                Number("42")
                FirstName("Russ")
                LastName("Miles")
            }
        }
    }

如果传入serviceURL,那么有效载荷在哪里?

有人可以详细解释一下这个sn-p吗?

【问题讨论】:

  • 看起来payload被插件注入了某种方法拦截。
  • 看起来大括号中的东西是有效载荷(HolidayRequest)。也许 Groovy 有一些语法糖可以让您以这种方式指定函数参数?尝试通过调用printSum(5) { 7 } 或类似的方式对其进行测试。

标签: groovy


【解决方案1】:

在上述实现中,withEndpointRequest 是一个带有两个参数的闭包。

withEndpointRequest(String serviceUrl, Closure payload).

当您从客户那里使用withEndpointRequest 时,您实际上是在这样做

    def namespace = "http://www.myveryimportantcompany.com/hr/schemas"
    def serviceURL = "http://localhost:8080/myapp/services"
    def payload = {
         HolidayRequest(xmlns: namespace) {
            Holiday {
                StartDate("2006-07-03")
                EndDate("2006-07-07")
            }
            Employee {
                Number("42")
                FirstName("Russ")
                LastName("Miles")
            }
        }
    }
    def response = withEndpointRequest(serviceURL, payload) 

通过将闭包声明为与withEndpointRequest 内联,使上述内容变得更加规范。 上面也可以写成

def response = withEndpointRequest(serviceURL, {
        //payload goes here as an inline closure as the second parameter
        HolidayRequest(xmlns: namespace) {
            Holiday {
                StartDate("2006-07-03")
                EndDate("2006-07-07")
            }
            Employee {
                Number("42")
                FirstName("Russ")
                LastName("Miles")
            }
        }
    })

不那么冗长。最后,它可以通过写成更精简和更时髦

def response = withEndpointRequest(serviceURL) {
        HolidayRequest(xmlns: namespace) {
            Holiday {
                StartDate("2006-07-03")
                EndDate("2006-07-07")
            }
            Employee {
                Number("42")
                FirstName("Russ")
                LastName("Miles")
            }
        }
    }

这里要注意的一点是Closure payload是最后一个参数。

现在,请注意,在调用 payload.call() 之前,不会调用闭包 (payload),如您在 SpringWS 插件中的问题中所述。

看看Closures as Method Arguments

我希望我能够传达您想了解的内容。 :)

【讨论】:

    【解决方案2】:

    here 发布的以下片段概述了用于将闭包传递给方法的几个选项。

    带有两个参数的方法。最后一个参数是一个闭包。

    def work(input, cl) {
        cl(input)
    }
    

    定义一个闭包。

    def assertJava = {
        it == 'Java'
    }
    

    将闭包传递给方法的方式

    work('Java', assertJava)
    
    work 'Java', assertJava  // No parenthesis.
    
    work('Groovy', {
        assert it == 'Groovy'
    })  // Anonymous closure as argument.
    
    work('Groovy') {
        assert it == 'Groovy'
    }  // Last argument is closure and can be outside parenthesis. 
    
    work('Groovy')
    {
         assert it == 'Groovy'
    }  // Opening bracket on new line. If we want a code block (e.g. static initializer) instead of closure we must use ; to separate code.
    
    
    work 'Groovy', {
        assert it == 'Groovy'
    }  // Pay attention, no parenthesis, so comma is needed again!
    
    
    // Does not work:
    //
    // Comma between argument list needed:
    // work 'Groovy' {
    //     assert it == 'Groovy'
    // }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-07-26
      • 2011-01-02
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多