我目前正在尝试了解递归问题。此代码检查节点是否为叶节点,如果是,则会增加叶节点的数量。
我无法理解fn.call(this)的作用,然后如何在for循环中调用闭包。
这是我的代码。
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++}
答案 0 :(得分:4)
我希望我能够正确地遵循,但似乎你有两个问题:
<强> 1。 fn.call(this)
做了什么?
首先,Closure是一个匿名的代码块,可以在以后执行。
当您调用testTreeNode.walkTree
时,您将传递Closure(匿名代码块)node -> if (node.leaf) leafCount++
作为walkTree
方法的参数,以便闭包成为名为{{1的变量在fn
。
在walkTree
方法中,然后使用Closure.call(args)方法显式调用Closure(代码块)。
请参阅:http://groovy-lang.org/closures.html#_calling_a_closure
<强> 2。如何在for循环中执行闭包?
由于可以使用walkTree
变量名来引用闭包,因此您可以将其作为参数直接传递给循环中的每个子TreeNode的fn
,然后调用该闭包使用walkTree
。
如果我们用传递的代码块替换Closure用法,可能会更清楚发生了什么:
fn.call(this)