简体   繁体   English

Groovy中的递归与关闭

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM