在 Groovy 中嵌套多个闭包

Nesting multiple Closures in Groovy

提问人:Jazzschmidt 提问时间:8/20/2021 更新时间:8/20/2021 访问量:180

问:

我在 Groovy 中嵌套多个 Closure 时遇到问题。只嵌套一个就像一个魅力:

def nestedClosure = { Closure cl -> doSomething { cl() } }

但是,我如何以编程方式从例如闭包列表中嵌套多个闭包?

假设这个例子:

Closure main = { println "Hello world" }

Closure consumer1 = { x -> println("1"); x(); println("1 END") }
Closure consumer2 = { x -> println("2"); x(); println("2 END") }
Closure consumer3 = { x -> println("3"); x(); println("3 END") }

我想以某种方式链接和嵌套这些消费者以获得以下输出:

1
2
3
Hello world
3 END
2 END
1 END

尝试了咖喱、疯狂的循环和谷歌搜索很长一段时间了,但似乎无法得到任何可行的想法。

时髦 的函数式编程 闭包

评论


答:

2赞 Jazzschmidt 8/20/2021 #1

诀窍是用最深的嵌套“main”Closure 来整理最后一个 Closure,然后连续整理剩余的 Closure 并覆盖 main:

def main = { println "Hallo" }

Closure consumer1 = { x -> println("1"); x(); println("1 END") }
Closure consumer2 = { x -> println("2"); x(); println("2 END") }
Closure consumer3 = { x -> println("3"); x(); println("3 END") }

def consumers = [consumer1, consumer2, consumer3]

// Nest main in last closure
consumers.reverse().each {
    main = it.curry(main)
}

main()

注意:由于我在内部习惯于保持参数安全,因此我需要通过方法指针进行调整:Consumer<Closure>Consumer.accept

def main = { println "Hallo" }

Consumer<Closure> consumer1 = { x -> println("1"); x(); println("1 END") }
Consumer<Closure> consumer2 = { x -> println("2"); x(); println("2 END") }
Consumer<Closure> consumer3 = { x -> println("3"); x(); println("3 END") }

def consumers = [consumer1, consumer2, consumer3]

consumers.reverse().each {
    main = it.&accept.curry(main)
}

main()

评论

1赞 cfrick 8/20/2021
对于风格,而不是高尔夫:您可以减少()而不是迭代和修改捕获的内容。inject
0赞 Jazzschmidt 8/20/2021
@cfrick 听起来很复杂,您能举个例子吗?
1赞 cfrick 8/20/2021
粗略(如未经测试):def mainPrime = consumers.reverse().inject(main, { acc, f -> f.&accept.curry(acc) })
0赞 Jazzschmidt 8/20/2021
太棒了!