[英]Recursion in Groovy with closure
I am currently trying to understand a problem with recursion. 我目前正在尝试了解递归问题。 This code checks to see if a node is a leaf node, if it is it will increment the amount of leaf nodes.
此代码检查节点是否为叶节点,如果是,它将增加叶节点的数量。
I can't understand what the fn.call(this) does and then how it then calls the closure inside the for loop. 我不明白fn.call(this)的作用,然后又如何在for循环中调用闭包。
Here is my code. 这是我的代码。
class TreeNode {
String name
List<TreeNode> children = []
// if no children, there is no leaf node
boolean isLeaf() {
return !children
}
void walkTree(Closure fn) {
fn.call(this)
for (child in children) {
child.walkTree(fn)
}
}
}
testTreeNode = new TreeNode(name: "Fred", children: [
new TreeNode(name: "Janet", children: [
new TreeNode(name: "Mark"),
new TreeNode(name: "Anne", children: [new TreeNode(name: "Simon") ]),
new TreeNode(name: "Kelly")
]),
new TreeNode(name: "Nigel")
])
def leafCount = 0
testTreeNode.walkTree { node -> if (node.leaf) leafCount++}
I hope I'm following correctly, but it seems you have 2 questions: 希望我能正确追踪,但看来您有2个问题:
1. What does fn.call(this)
do? 1.
fn.call(this)
什么作用?
Firstly, a Closure is an anonymous block of code that can be executed at a later time. 首先,闭包是可以在以后执行的匿名代码块。
When you call testTreeNode.walkTree
, you are passing the Closure (block of anonymous code) node -> if (node.leaf) leafCount++
as a parameter of the walkTree
method, so that closure becomes the variable named fn
within the context of walkTree
. 当您调用
testTreeNode.walkTree
,您将传递Closure(匿名代码块) node -> if (node.leaf) leafCount++
作为walkTree
方法的参数,因此,闭包成为walkTree
上下文中名为fn
的变量。
Within the walkTree
method, the Closure (block of code) is then being explicitly invoked using the Closure.call(args) method. 然后在
walkTree
方法中,使用Closure.call(args)方法显式调用Closure(代码块)。
See: http://groovy-lang.org/closures.html#_calling_a_closure 请参阅: http : //groovy-lang.org/closures.html#_calling_a_closure
2. How is the closure executed inside the for loop? 2.在for循环中如何执行闭包?
As the closure can be referred to using the fn
variable name, you are then able to pass that as an argument directly to walkTree
for each child TreeNode in the loop, which then invokes that closure using fn.call(this)
. 由于可以使用
fn
变量名来引用闭包,因此您可以将其作为参数直接传递给walkTree
中每个子TreeNode的walkTree
,然后使用fn.call(this)
调用该闭包。
If we substitute the Closure usage with the block of code passed, it might be clearer what is happening: 如果我们用传递的代码块代替Closure用法,那么可能会更清楚发生了什么:
void walkTree(Closure fn) {
//Closure executed here
if (this.leaf) leafCount++
for (child in children) {
//closure passed as argument to walkTree method of child TreeNodes
child.walkTree { node -> if (node.leaf) leafCount++ }
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.