如何label以这种方式调用该函数并将其设置为最后一个参数的闭包?仅当我label使用括号调用但我不需要它们时,此代码才有效。是否可以在没有它们的情况下将闭包设置为功能?
label = { name, callback ->
callback()
}
label "lbl" { // not works
println "call $it"
}
label ("lbl") { // works
println "call $it"
}
Run Code Online (Sandbox Code Playgroud)
如果您不想使用括号,那么您必须拆分闭包参数,以告诉编译器您要label使用以下两个参数执行:
label "lbl", {
println "call $it"
}
Run Code Online (Sandbox Code Playgroud)
这个符号相当于:
label("lbl", {
println "call $it"
})
Run Code Online (Sandbox Code Playgroud)
Groovy 具有这种语法糖,当闭包是函数原型的最后一个参数时,它允许您在括号外传递闭包,这就是以下符号起作用的原因:
label ("lbl") {
println "call $it"
}
Run Code Online (Sandbox Code Playgroud)
但它仍然相当于前面提到的那些。
如何做出
label "lbl" { }有效的陈述?如果你真的想编译如下代码:
Run Code Online (Sandbox Code Playgroud)label "lbl" { println "call $it" }您需要注意一件事 - 这种符号相当于:
Run Code Online (Sandbox Code Playgroud)label("lbl" { println "call $it" })这意味着有一个
label接受单个参数的函数- 从接受单个参数的函数返回的值lbl- 闭包。这些函数的实现可能如下所示:Run Code Online (Sandbox Code Playgroud)def label = { value -> // do something with value println "The value accepted by label function is '${value}'" } def lbl = { callback -> callback?.call() } label "lbl" { println "call $it" }它编译并将以下输出打印到控制台:
Run Code Online (Sandbox Code Playgroud)call null The value accepted by label function is 'null'当然,正如您所看到的,您必须实现方法,
lbl并且在大多数情况下这是非常有限的 - 您不能label使用不同于lbl. 您可以实现 Groovy 的methodMissing(name, args)函数,每当调用不存在的方法时都会调用该函数。考虑以下示例:Run Code Online (Sandbox Code Playgroud)def methodMissing(String name, args) { if (args.length == 1 && args[0] instanceof Closure) { println "Running missing method '${name}'" return args[0].call() } throw new MissingMethodException(name, this.class, args) } def label = { value -> // do something with value println "The value accepted by label function is '${value}'" } def lbl = { callback -> callback?.call() } label "lbl" { println "call $it" } label "test" { println "nothing" }在这种情况下,当
label "test" { println "nothing" }被调用时,Groovy 会使用,missingMethod因为test运行时上下文中不存在方法。Run Code Online (Sandbox Code Playgroud)call null The value accepted by label function is 'null' Running missing method 'test' nothing The value accepted by label function is 'null'但是,这并不意味着您可以将其视为从代码中去除逗号分隔符或括号的等价物。这是一个用 Groovy 编写的简单 DSL 的示例,它使用
methodMissing机制来满足不存在的方法调用。最后一个示例实际上与以下示例相同:Run Code Online (Sandbox Code Playgroud)label("test" { println "nothing" })一个需要单个参数的函数,在这种情况下,我们将它作为
test具有单个参数的方法调用的结果提供{ println "nothing" }。我强烈建议接受这样一个事实,即 Groovy 要求您使用 coma 分隔函数参数,并且不要使用此类 DSL 从代码中删除 coma 或括号。Groovy DSL 非常强大,当您决定在代码中使用此工具时,您必须知道自己在做什么。例如,想想如果你打电话会发生什么:
Run Code Online (Sandbox Code Playgroud)label "test" { println "something" }出于某种原因,一个方法定义为以下闭包:
Run Code Online (Sandbox Code Playgroud)def test = { int num -> num + 2 }存在于您的班级中。您将开始收到异常,因为
methodMissing在这种情况下不再被调用。方法test存在,但它没有接受单个闭包的签名。
| 归档时间: |
|
| 查看次数: |
771 次 |
| 最近记录: |