grails - 为什么这个 Groovy 闭包没有返回我期望的值?

标签 grails groovy

在 Grails 应用程序中,我试图防止在有向图中创建循环。用户可以为节点分配父节点,但任何节点都不应该是其父节点的祖先。我编写了一个调用 checkLineageForTarget 的简单设置函数,它是执行繁重工作的递归函数:

boolean checkLineageForTarget(Integer target, Collection<Node>stillToProcess){
// true means that this is a safe addition
// false means that this addition creates a cycle

    boolean retVal = stillToProcess.each {
        Collection<Node> itsParents = getParentNodes(it)

        if (it.id == target){
            println("found a loop on " + target);
            return false; // loop detected!
        }
        if (itsParents.empty){ return true; } // end of the line

        return checkLineageForTarget(target, itsParents)
    }

    // at this point, retVal is always true, even when the "found a loop [...]" condition is met
    return retVal;
}

这个“有效”,因为它打印“找到一个循环 [...]”消息,但在闭包之外,retVal 为真,调用函数尝试添加新的父/子关系,而我的堆栈溢出。

我的误解是什么?

最佳答案

each方法返回调用它的同一个集合,因此 retVal 可能不是 bool 值“true”,但被评估为“真实”(因为它是一个集合,这意味着它不是空的)。

如果要检查集合中每个元素的条件,可以使用 every .

boolean checkLineageForTarget(Integer target, Collection<Node>stillToProcess){
    stillToProcess.every { node ->
        node.id != target && checkLineageForTarget(target, getParentNodes(node))
    }
}

请注意,我不需要检查父节点集合上的 .empty 条件,因为这将被对 checkLineageForTarget 的递归调用过滤(即调用 .every在空集合上总是返回 true)。此外,由于 && 运算符的短路,迭代在 node.id == target 时立即停止 :)

关于grails - 为什么这个 Groovy 闭包没有返回我期望的值?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9387641/

相关文章:

java - 使用 spock 测试重载的 java 方法

caching - 在 Grails 中缓存昂贵的 Web 服务调用的最佳策略

unit-testing - 如何在Grails 2.3.x中禁用自动生成的单元测试

grails - 如何使用3.1.6版在GGTS中创建grails项目

java - 来自 block API "Jar"部分的 gradle java 插件 "from"任务

Groovy 强制 List 到 Map 不会抛出 ClassCastException 或者什么是 ArrayList1_groovyProxy?

grails - 获取错误编译期间发生 fatal error org.apache.tools.ant.BuildException:编译失败。在grails应用程序中

Grails Gorm 捕获外键约束错误

grails - Sonar 5.1.1 与 Groovy Plugin 1.1.1 项目始终报告 0.0 天的技术债务

java - 如何使用 Groovy 将子集从字符串数组复制到整数数组?