Groovy 中带闭包的递归

poc*_*ckn 0 recursion groovy closures

我目前正在尝试理解递归问题。此代码检查节点是否是叶节点,如果是,则会增加叶节点的数量。

我无法理解 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++}
Run Code Online (Sandbox Code Playgroud)

小智 5

我希望我的理解是正确的,但你似乎有两个问题:

1.fn.call(this)做什么?

首先,闭包是一个可以稍后执行的匿名代码块。

当您调用 时,您将闭包(匿名代码块)作为方法的参数testTreeNode.walkTree传递,以便闭包成为上下文中命名的变量。node -> if (node.leaf) leafCount++walkTreefnwalkTree

在该walkTree方法内,然后使用 Closure.call(args) 方法显式调用 Closure(代码块)。

请参阅: http: //groovy-lang.org/closures.html#_calling_a_closure

2. for循环内部的闭包是如何执行的?

由于可以使用变量名引用闭包fn,因此您可以将其作为参数直接传递给walkTree循环中的每个子 TreeNode,然后使用 调用该闭包fn.call(this)

如果我们用传递的代码块替换 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++ }
    }
}
Run Code Online (Sandbox Code Playgroud)