如何基于指定列表动态创建嵌套调用的Groovy Closure?
动态生成嵌套调用的Groovy闭包
要根据给定列表动态生成嵌套闭包,实现类似示例中的嵌套调用效果,可以通过递归构建闭包的方式实现,这种方式简洁且符合Groovy的函数式风格。
解决方案:递归构建嵌套闭包
核心思路是利用递归,为列表中的每个元素生成对应的闭包层级:每个闭包先打印当前元素,再递归处理剩余元素的闭包并调用,最后再次打印当前元素。
List<String> commands = ["First", "Second", "Third"] def buildNestedClosure(List<String> cmds) { // 递归终止条件:列表为空时返回空闭包 if (cmds.isEmpty()) { return { } } String currentCmd = cmds[0] List<String> remainingCmds = cmds.drop(1) return { println(currentCmd) // 递归构建内层闭包并调用 def innerClosure = buildNestedClosure(remainingCmds) innerClosure.call() println(currentCmd) } } // 生成最终的执行闭包并调用 Closure execute = buildNestedClosure(commands) execute.call()
执行结果
运行上述代码,输出与预期完全一致:
First Second Third Second First
备选方案:字符串拼接+Eval执行
如果需要生成与示例完全一致的代码结构字符串,再执行,可以通过拼接代码字符串,结合Eval.me执行:
List<String> commands = ["First", "Second", "Third"] // 构建闭包代码字符串 def codeBuilder = new StringBuilder("Closure execute = {") // 构建闭包嵌套的前半部分(打印元素+定义内层闭包) commands.eachWithIndex { cmd, idx -> String indent = " " * (idx + 1) codeBuilder.append("\n${indent}println(\"$cmd\")") if (idx < commands.size() - 1) { codeBuilder.append("\n${indent}Closure inner${idx+1} = {") } } // 构建闭包嵌套的后半部分(调用内层闭包+打印元素) commands.drop(1).eachWithIndex { _, idx -> int level = commands.size() - idx - 1 String indent = " " * level codeBuilder.append("\n${indent}}.call()") codeBuilder.append("\n${indent}println(\"${commands[level-1]}\")") } // 闭合最外层闭包并添加调用语句 codeBuilder.append("\n}") codeBuilder.append("\nexecute.call()") // 执行生成的代码 Eval.me(codeBuilder.toString())
这种方式完全复刻了示例中的代码结构,但相比递归方式,可读性和维护性稍差,更适合需要精确控制代码字符串的场景。
内容的提问来源于stack exchange,提问作者jeffery
相关产品推荐
相关产品推荐

