英文:
Dynamically create Groovy closures
问题
以下是根据您提供的代码示例和列表创建动态闭包代码的翻译部分:
// 创建一个执行闭包
Closure execute = {
println("First")
// 遍历命令列表,并为每个命令创建闭包并调用
List<String> commands = ["First", "Second", "Third"]
commands.each { command ->
Closure closure = {
println(command)
}
closure.call()
}
println("First")
}
// 调用执行闭包
execute.call()
请注意,这段代码在Groovy语言中编写,用于动态创建闭包并根据命令列表调用它们。不包括代码的其他部分。
如果您需要更多帮助或有其他问题,请随时提出。
英文:
I have the need to dynamically create closures which should call other closures within itself.
Here is an example of what I expect the resulting code to do
Closure execute = {
println("First")
Closure second = {
println("Second")
Closure third = {
println("Third")
}.call()
println("Second")
}.call()
println("First")
}
execute.call()
The above results in the following output:
First
Second
Third
Second
First
How can I create the above closure code dynamically given the following list:
List<String> commands = ["First", "Second", "Third"]
Any pointers appreciated.
答案1
得分: 2
以下是翻译好的部分:
所以,让我们创建一个返回闭包的函数:
def wrap(String name, Closure cl = null) {
{ ->
println(name)
// 如果传递了一个闭包,就执行它并再次打印名称
if (cl) {
cl()
println(name)
}
}
}
然后,获取我们的命令列表:
List<String> commands = ["First", "Second", "Third"]
并将当前闭包存储在一个变量中:
Closure current = null
接下来,让我们反向遍历列表,创建一个新的闭包,并包装前一个闭包:
commands.reverse().each {
current = wrap(it, current)
}
然后,我们可以运行最终的闭包:
current()
然后我们得到以下输出:
First
Second
Third
Second
First
在非 Jenkins Groovy 中,您可以使用 inject
代替带有变异变量的 each
:
Closure current = commands.reverse().inject(null) { curr, command ->
wrap(command, curr)
}
但根据我回答 Jenkins 问题的经验,inject
很少有效,所以请坚持使用第一种方式。
英文:
So, lets make a function which returns a closure
def wrap(String name, Closure cl = null) {
{ ->
println(name)
// If we were passed a closure, then run it and print the name again
if (cl) {
cl()
println(name)
}
}
}
Then, take our list of commands
List<String> commands = ["First", "Second", "Third"]
And store the current closure in a variable
Closure current = null
Then, lets go backwards through the list, creating a new closure, and wrapping the previous one
commands.reverse().each {
current = wrap(it, current)
}
Then we can run the final closure:
current()
And we get the output:
First
Second
Third
Second
First
🎉
In non-jenkins groovy you can use inject instead of the each with a mutating variable:
Closure current = commands.reverse().inject(null) { curr, command ->
wrap(command, curr)
}
But in my experience of answering Jenkins questions, inject
rarely works, so stick with the first way
答案2
得分: 0
你可以将闭包存储在变量中,然后将这些变量存储在列表中。
Closure first = {
println("First")
}
Closure second = {
println("Second")
}
Closure third = {
println("Third")
second()
}
List<Closure> execute = [first, second, third]
execute*.call()
输出:
First
Second
Third
Second
英文:
You can store closures in variables and store those variables in a list
Closure first = {
println("First")
}
Closure second = {
println("Second")
}
Closure third = {
println("Third")
second()
}
List<Closure> execute = [first, second, third]
execute*.call()
Output:
First
Second
Third
Second
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论